Externals: Update glslang to upstream commit 32d3ec3
This commit is contained in:
parent
160d16f1b3
commit
bc96557ec4
|
@ -7,7 +7,7 @@ version: "{build}"
|
||||||
os: Visual Studio 2013
|
os: Visual Studio 2013
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
- Any CPU
|
- x64
|
||||||
|
|
||||||
configuration:
|
configuration:
|
||||||
- Debug
|
- Debug
|
||||||
|
@ -17,6 +17,13 @@ branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
|
# Travis advances the master-tot tag to current top of the tree after
|
||||||
|
# each push into the master branch, because it relies on that tag to
|
||||||
|
# upload build artifacts to the master-tot release. This will cause
|
||||||
|
# double testing for each push on Appveyor: one for the push, one for
|
||||||
|
# the tag advance. Disable testing tags.
|
||||||
|
skip_tags: true
|
||||||
|
|
||||||
clone_depth: 5
|
clone_depth: 5
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -25,6 +32,7 @@ matrix:
|
||||||
# scripts that run after cloning repository
|
# scripts that run after cloning repository
|
||||||
install:
|
install:
|
||||||
- git clone https://github.com/google/googletest.git External/googletest
|
- git clone https://github.com/google/googletest.git External/googletest
|
||||||
|
- C:/Python27/python.exe update_glslang_sources.py
|
||||||
|
|
||||||
build:
|
build:
|
||||||
parallel: true # enable MSBuild parallel builds
|
parallel: true # enable MSBuild parallel builds
|
||||||
|
@ -38,3 +46,45 @@ build_script:
|
||||||
test_script:
|
test_script:
|
||||||
- ctest -C %CONFIGURATION% --output-on-failure
|
- ctest -C %CONFIGURATION% --output-on-failure
|
||||||
- cd ../Test && bash runtests
|
- cd ../Test && bash runtests
|
||||||
|
- cd ../build
|
||||||
|
|
||||||
|
after_test:
|
||||||
|
# For debug build, the generated dll has a postfix "d" in its name.
|
||||||
|
- ps: >-
|
||||||
|
If ($env:configuration -Match "Debug") {
|
||||||
|
$env:SUFFIX="d"
|
||||||
|
} Else {
|
||||||
|
$env:SUFFIX=""
|
||||||
|
}
|
||||||
|
- cd install
|
||||||
|
# Zip all glslang artifacts for uploading and deploying
|
||||||
|
- 7z a glslang-master-windows-"%PLATFORM%"-"%CONFIGURATION%".zip
|
||||||
|
bin\glslangValidator.exe
|
||||||
|
include\glslang\*
|
||||||
|
include\SPIRV\*
|
||||||
|
lib\glslang%SUFFIX%.lib
|
||||||
|
lib\HLSL%SUFFIX%.lib
|
||||||
|
lib\OGLCompiler%SUFFIX%.lib
|
||||||
|
lib\OSDependent%SUFFIX%.lib
|
||||||
|
lib\SPIRV%SUFFIX%.lib
|
||||||
|
lib\SPVRemapper%SUFFIX%.lib
|
||||||
|
lib\SPIRV-Tools%SUFFIX%.lib
|
||||||
|
lib\SPIRV-Tools-opt%SUFFIX%.lib
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: build\install\*.zip
|
||||||
|
name: artifacts-zip
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
- provider: GitHub
|
||||||
|
auth_token:
|
||||||
|
secure: YglcSYdl0TylEa59H4K6lylBEDr586NAt2EMgZquSo+iuPrwgZQuJLPCoihSm9y6
|
||||||
|
release: master-tot
|
||||||
|
description: "Continuous build of the latest master branch by Appveyor and Travis CI"
|
||||||
|
artifact: artifacts-zip
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
force_update: true
|
||||||
|
on:
|
||||||
|
branch: master
|
||||||
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
# test files have a mix of lf/crlf, and that's a good thing, for testing, don't mess with it
|
||||||
|
# bash scripts need lines ending with lf, and that's correct for Windows too, e.g., under Cygwin
|
||||||
|
# (scripts often don't have a suffix)
|
||||||
|
* -text
|
||||||
|
*.sh text eof=lf
|
||||||
|
|
||||||
|
# txt files should be native and normalized
|
||||||
|
*.txt text
|
||||||
|
|
||||||
|
# source code can be native and normalized, but simpler if lf everywhere; will try that way
|
||||||
|
*.h text eof=lf
|
||||||
|
*.c text eof=lf
|
||||||
|
*.cpp text eof=lf
|
||||||
|
*.y text eof=lf
|
||||||
|
*.out text eof=lf
|
||||||
|
*.conf text eof=lf
|
||||||
|
*.err text eof=lf
|
|
@ -0,0 +1,10 @@
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.exe
|
||||||
|
tags
|
||||||
|
TAGS
|
||||||
|
build/
|
||||||
|
Test/localResults/
|
||||||
|
External/googletest
|
||||||
|
External/spirv-tools
|
|
@ -7,10 +7,13 @@ os:
|
||||||
- osx
|
- osx
|
||||||
|
|
||||||
# Use Ubuntu 14.04 LTS (Trusty) as the Linux testing environment.
|
# Use Ubuntu 14.04 LTS (Trusty) as the Linux testing environment.
|
||||||
sudo: required
|
sudo: false
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
global:
|
||||||
|
- secure: aGFrgzyKp+84hKrGkxVWg8cHV61uqrKEHT38gfSQK6+WS4GfLOyH83p7WnsEBb7AMhzU7LMNFdvOFr6+NaMpVnqRvc40CEG1Q+lNg9Pq9mhIZLowvDrfqTL9kQ+8Nbw5Q6/dg6CTvY7fvRfpfCEmKIUZBRkoKUuHeuM1uy3IupFcdNuL5bSYn3Beo+apSJginh9DI4BLDXFUgBzTRSLLyCX5g3cpaeGGOCr8quJlYx75W6HRck5g9SZuLtUoH9GFEV3l+ZEWB8noErW+J56L03bwNwFuuAh321evw++oQk5KFa8rlDvar3SJ3b1RHB8u/eq5DBYMyaK/fS8+Q7QbGr8diF/wDe68bKO7U9IhpNfExXmczCpExjHomW5TQv4rYdGhygPMfW97aIsPRYyNKcl4fkmb7NDrM8w0Jscdq2g5c2Kz0ItyZoBri/NXLwFQQjaVCs7Pf97TjuMA7mK0GJmDTRzi6SrDYlWMt5BQL3y0CCojyfLIRcTh0CQjQI29s97bLfQrYAxt9GNNFR+HTXRLLrkaAlJkPGEPwUywlSfEThnvHLesNxYqemolAYpQT4ithoL4GehGIHmaxsW295aKVhuRf8K9eBODNqrfblvM42UHhjntT+92ZnQ/Gkq80GqaMxnxi4PO5FyPIxt0r981b54YBkWi8YA4P7w5pNI=
|
||||||
|
matrix:
|
||||||
- GLSLANG_BUILD_TYPE=Release
|
- GLSLANG_BUILD_TYPE=Release
|
||||||
- GLSLANG_BUILD_TYPE=Debug
|
- GLSLANG_BUILD_TYPE=Debug
|
||||||
|
|
||||||
|
@ -24,6 +27,9 @@ matrix:
|
||||||
# Skip GCC builds on Mac OS X.
|
# Skip GCC builds on Mac OS X.
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
include:
|
||||||
|
# Additional build using Android NDK.
|
||||||
|
- env: BUILD_NDK=ON
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
apt: true
|
apt: true
|
||||||
|
@ -36,25 +42,82 @@ addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- clang-3.6
|
- clang-3.6
|
||||||
- ninja-build
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# Install ninja on Mac OS X.
|
# Make sure that clang-3.6 is selected on Linux.
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew install ninja; fi
|
|
||||||
# Make sure that clang-3.6 is selected.
|
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "clang" ]]; then
|
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "clang" ]]; then
|
||||||
export CC=clang-3.6 CXX=clang++-3.6;
|
export CC=clang-3.6 CXX=clang++-3.6;
|
||||||
fi
|
fi
|
||||||
|
# Download Android NDK and Android CMake toolchain file.
|
||||||
|
- if [[ "$BUILD_NDK" == "ON" ]]; then
|
||||||
|
git clone --depth=1 https://github.com/urho3d/android-ndk.git $HOME/android-ndk;
|
||||||
|
export ANDROID_NDK=$HOME/android-ndk;
|
||||||
|
git clone --depth=1 https://github.com/taka-no-me/android-cmake.git $HOME/android-cmake;
|
||||||
|
export TOOLCHAIN_PATH=$HOME/android-cmake/android.toolchain.cmake;
|
||||||
|
fi
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- git clone https://github.com/google/googletest.git External/googletest
|
- git clone --depth=1 https://github.com/google/googletest.git External/googletest
|
||||||
|
- ./update_glslang_sources.py
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- mkdir build && cd build
|
- mkdir build && cd build
|
||||||
# We need to install the compiled binaries so the paths in the runtests script can resolve correctly.
|
# For Android, do release building using NDK without testing.
|
||||||
- cmake -GNinja -DCMAKE_BUILD_TYPE=${GLSLANG_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=`pwd`/install ..
|
# For Linux and macOS, do debug/release building with testing.
|
||||||
- ninja install
|
- if [[ "$BUILD_NDK" == "ON" ]]; then
|
||||||
# Run Google-Test-based tests.
|
cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_PATH}
|
||||||
- ctest --output-on-failure
|
-DANDROID_NATIVE_API_LEVEL=android-12
|
||||||
# Run runtests-based tests.
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
- cd ../Test && ./runtests
|
-DANDROID_ABI="armeabi-v7a with NEON"
|
||||||
|
-DBUILD_TESTING=OFF ..;
|
||||||
|
make -j4;
|
||||||
|
else
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=${GLSLANG_BUILD_TYPE}
|
||||||
|
-DCMAKE_INSTALL_PREFIX=`pwd`/install ..;
|
||||||
|
make -j4 install;
|
||||||
|
ctest --output-on-failure &&
|
||||||
|
cd ../Test && ./runtests;
|
||||||
|
fi
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
# For debug build, the generated dll has a postfix "d" in its name.
|
||||||
|
- if [[ "${GLSLANG_BUILD_TYPE}" == "Debug" ]]; then
|
||||||
|
export SUFFIX="d";
|
||||||
|
else
|
||||||
|
export SUFFIX="";
|
||||||
|
fi
|
||||||
|
# Create tarball for deployment
|
||||||
|
- if [[ ${CC} == clang* && "${BUILD_NDK}" != "ON" ]]; then
|
||||||
|
cd ../build/install;
|
||||||
|
export TARBALL=glslang-master-${TRAVIS_OS_NAME}-${GLSLANG_BUILD_TYPE}.zip;
|
||||||
|
zip ${TARBALL}
|
||||||
|
bin/glslangValidator
|
||||||
|
include/glslang/*
|
||||||
|
include/SPIRV/*
|
||||||
|
lib/libglslang${SUFFIX}.a
|
||||||
|
lib/libHLSL${SUFFIX}.a
|
||||||
|
lib/libOGLCompiler${SUFFIX}.a
|
||||||
|
lib/libOSDependent${SUFFIX}.a
|
||||||
|
lib/libSPIRV${SUFFIX}.a
|
||||||
|
lib/libSPVRemapper${SUFFIX}.a
|
||||||
|
lib/libSPIRV-Tools${SUFFIX}.a
|
||||||
|
lib/libSPIRV-Tools-opt${SUFFIX}.a;
|
||||||
|
fi
|
||||||
|
|
||||||
|
before_deploy:
|
||||||
|
# Tag the current top of the tree as "master-tot".
|
||||||
|
# Travis CI replies on the tag name to properly push to GitHub Releases.
|
||||||
|
- git config --global user.name "Travis CI"
|
||||||
|
- git config --global user.email "builds@travis-ci.org"
|
||||||
|
- git tag -f master-tot
|
||||||
|
- git push -q -f https://${glslangtoken}@github.com/KhronosGroup/glslang --tags
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
api_key: ${glslangtoken}
|
||||||
|
on:
|
||||||
|
branch: master
|
||||||
|
condition: ${CC} == clang* && ${BUILD_NDK} != ON
|
||||||
|
file: ${TARBALL}
|
||||||
|
skip_cleanup: true
|
||||||
|
overwrite: true
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
set(SRCS
|
set(SRCS
|
||||||
glslang/GenericCodeGen/CodeGen.cpp
|
glslang/GenericCodeGen/CodeGen.cpp
|
||||||
glslang/GenericCodeGen/Link.cpp
|
glslang/GenericCodeGen/Link.cpp
|
||||||
|
glslang/MachineIndependent/attribute.cpp
|
||||||
glslang/MachineIndependent/Constant.cpp
|
glslang/MachineIndependent/Constant.cpp
|
||||||
glslang/MachineIndependent/glslang_tab.cpp
|
glslang/MachineIndependent/glslang_tab.cpp
|
||||||
glslang/MachineIndependent/InfoSink.cpp
|
glslang/MachineIndependent/InfoSink.cpp
|
||||||
|
@ -8,17 +9,17 @@ set(SRCS
|
||||||
glslang/MachineIndependent/Intermediate.cpp
|
glslang/MachineIndependent/Intermediate.cpp
|
||||||
glslang/MachineIndependent/intermOut.cpp
|
glslang/MachineIndependent/intermOut.cpp
|
||||||
glslang/MachineIndependent/IntermTraverse.cpp
|
glslang/MachineIndependent/IntermTraverse.cpp
|
||||||
|
glslang/MachineIndependent/iomapper.cpp
|
||||||
glslang/MachineIndependent/limits.cpp
|
glslang/MachineIndependent/limits.cpp
|
||||||
glslang/MachineIndependent/linkValidate.cpp
|
glslang/MachineIndependent/linkValidate.cpp
|
||||||
glslang/MachineIndependent/parseConst.cpp
|
glslang/MachineIndependent/parseConst.cpp
|
||||||
|
glslang/MachineIndependent/ParseContextBase.cpp
|
||||||
glslang/MachineIndependent/ParseHelper.cpp
|
glslang/MachineIndependent/ParseHelper.cpp
|
||||||
glslang/MachineIndependent/PoolAlloc.cpp
|
glslang/MachineIndependent/PoolAlloc.cpp
|
||||||
glslang/MachineIndependent/preprocessor/Pp.cpp
|
glslang/MachineIndependent/preprocessor/Pp.cpp
|
||||||
glslang/MachineIndependent/preprocessor/PpAtom.cpp
|
glslang/MachineIndependent/preprocessor/PpAtom.cpp
|
||||||
glslang/MachineIndependent/preprocessor/PpContext.cpp
|
glslang/MachineIndependent/preprocessor/PpContext.cpp
|
||||||
glslang/MachineIndependent/preprocessor/PpMemory.cpp
|
|
||||||
glslang/MachineIndependent/preprocessor/PpScanner.cpp
|
glslang/MachineIndependent/preprocessor/PpScanner.cpp
|
||||||
glslang/MachineIndependent/preprocessor/PpSymbols.cpp
|
|
||||||
glslang/MachineIndependent/preprocessor/PpTokens.cpp
|
glslang/MachineIndependent/preprocessor/PpTokens.cpp
|
||||||
glslang/MachineIndependent/propagateNoContraction.cpp
|
glslang/MachineIndependent/propagateNoContraction.cpp
|
||||||
glslang/MachineIndependent/reflection.cpp
|
glslang/MachineIndependent/reflection.cpp
|
||||||
|
@ -27,13 +28,6 @@ set(SRCS
|
||||||
glslang/MachineIndependent/ShaderLang.cpp
|
glslang/MachineIndependent/ShaderLang.cpp
|
||||||
glslang/MachineIndependent/SymbolTable.cpp
|
glslang/MachineIndependent/SymbolTable.cpp
|
||||||
glslang/MachineIndependent/Versions.cpp
|
glslang/MachineIndependent/Versions.cpp
|
||||||
|
|
||||||
hlsl/hlslGrammar.cpp
|
|
||||||
hlsl/hlslOpMap.cpp
|
|
||||||
hlsl/hlslParseables.cpp
|
|
||||||
hlsl/hlslParseHelper.cpp
|
|
||||||
hlsl/hlslScanContext.cpp
|
|
||||||
hlsl/hlslTokenStream.cpp
|
|
||||||
OGLCompilersDLL/InitializeDll.cpp
|
OGLCompilersDLL/InitializeDll.cpp
|
||||||
SPIRV/disassemble.cpp
|
SPIRV/disassemble.cpp
|
||||||
SPIRV/doc.cpp
|
SPIRV/doc.cpp
|
||||||
|
|
|
@ -1,46 +1,122 @@
|
||||||
|
# increase to 3.1 once all major distributions
|
||||||
|
# include a version of CMake >= 3.1
|
||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
if (POLICY CMP0048)
|
||||||
|
cmake_policy(SET CMP0048 NEW)
|
||||||
|
endif()
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
enable_testing()
|
# Adhere to GNU filesystem layout conventions
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "prefix")
|
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
|
||||||
|
|
||||||
|
set(LIB_TYPE STATIC)
|
||||||
|
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
set(LIB_TYPE SHARED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(SKIP_GLSLANG_INSTALL "Skip installation" ${SKIP_GLSLANG_INSTALL})
|
||||||
|
if(NOT ${SKIP_GLSLANG_INSTALL})
|
||||||
|
set(ENABLE_GLSLANG_INSTALL ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON)
|
||||||
|
option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON)
|
||||||
|
|
||||||
|
option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON)
|
||||||
|
|
||||||
|
option(ENABLE_HLSL "Enables HLSL input support" ON)
|
||||||
|
|
||||||
|
option(ENABLE_OPT "Enables spirv-opt capability if present" ON)
|
||||||
|
|
||||||
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND WIN32)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "..." FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
project(glslang)
|
project(glslang)
|
||||||
|
# make testing optional
|
||||||
|
include(CTest)
|
||||||
|
|
||||||
|
if(ENABLE_AMD_EXTENSIONS)
|
||||||
|
add_definitions(-DAMD_EXTENSIONS)
|
||||||
|
endif(ENABLE_AMD_EXTENSIONS)
|
||||||
|
|
||||||
|
if(ENABLE_NV_EXTENSIONS)
|
||||||
|
add_definitions(-DNV_EXTENSIONS)
|
||||||
|
endif(ENABLE_NV_EXTENSIONS)
|
||||||
|
|
||||||
|
if(ENABLE_HLSL)
|
||||||
|
add_definitions(-DENABLE_HLSL)
|
||||||
|
endif(ENABLE_HLSL)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(CMAKE_DEBUG_POSTFIX "d")
|
set(CMAKE_DEBUG_POSTFIX "d")
|
||||||
|
if(MSVC)
|
||||||
include(ChooseMSVCCRT.cmake)
|
include(ChooseMSVCCRT.cmake)
|
||||||
|
endif(MSVC)
|
||||||
add_definitions(-DGLSLANG_OSINCLUDE_WIN32)
|
add_definitions(-DGLSLANG_OSINCLUDE_WIN32)
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
add_definitions(-fPIC)
|
|
||||||
add_definitions(-DGLSLANG_OSINCLUDE_UNIX)
|
add_definitions(-DGLSLANG_OSINCLUDE_UNIX)
|
||||||
else(WIN32)
|
else(WIN32)
|
||||||
message("unknown platform")
|
message("unknown platform")
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
|
||||||
add_definitions(-std=c++11)
|
add_compile_options(-Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs
|
||||||
|
-Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -fno-exceptions)
|
||||||
|
add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over.
|
||||||
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||||
add_definitions(-std=c++11)
|
add_compile_options(-Wall -Wuninitialized -Wunused -Wunused-local-typedefs
|
||||||
|
-Wunused-parameter -Wunused-value -Wunused-variable)
|
||||||
|
add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over.
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Request C++11
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS 3.1)
|
||||||
|
# CMake versions before 3.1 do not understand CMAKE_CXX_STANDARD
|
||||||
|
# remove this block once CMake >=3.1 has fixated in the ecosystem
|
||||||
|
add_compile_options(-std=c++11)
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(glslang_set_link_args TARGET)
|
function(glslang_set_link_args TARGET)
|
||||||
# For MinGW compiles, statically link against the GCC and C++ runtimes.
|
# For MinGW compiles, statically link against the GCC and C++ runtimes.
|
||||||
# This avoids the need to ship those runtimes as DLLs.
|
# This avoids the need to ship those runtimes as DLLs.
|
||||||
if(WIN32)
|
if(WIN32 AND ${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
|
||||||
if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
|
|
||||||
set_target_properties(${TARGET} PROPERTIES
|
set_target_properties(${TARGET} PROPERTIES
|
||||||
LINK_FLAGS "-static -static-libgcc -static-libstdc++")
|
LINK_FLAGS "-static -static-libgcc -static-libstdc++")
|
||||||
endif()
|
endif()
|
||||||
endif(WIN32)
|
|
||||||
endfunction(glslang_set_link_args)
|
endfunction(glslang_set_link_args)
|
||||||
|
|
||||||
# We depend on these for later projects, so they should come first.
|
# We depend on these for later projects, so they should come first.
|
||||||
add_subdirectory(External)
|
add_subdirectory(External)
|
||||||
|
|
||||||
|
if(NOT TARGET SPIRV-Tools-opt)
|
||||||
|
set(ENABLE_OPT OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_OPT)
|
||||||
|
message(STATUS "optimizer enabled")
|
||||||
|
add_definitions(-DENABLE_OPT=1)
|
||||||
|
else()
|
||||||
|
if(ENABLE_HLSL)
|
||||||
|
message(STATUS "spirv-tools not linked - illegal SPIRV may be generated for HLSL")
|
||||||
|
endif()
|
||||||
|
add_definitions(-DENABLE_OPT=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(glslang)
|
add_subdirectory(glslang)
|
||||||
add_subdirectory(OGLCompilersDLL)
|
add_subdirectory(OGLCompilersDLL)
|
||||||
add_subdirectory(StandAlone)
|
if(ENABLE_GLSLANG_BINARIES)
|
||||||
|
add_subdirectory(StandAlone)
|
||||||
|
endif()
|
||||||
add_subdirectory(SPIRV)
|
add_subdirectory(SPIRV)
|
||||||
add_subdirectory(hlsl)
|
if(ENABLE_HLSL)
|
||||||
|
add_subdirectory(hlsl)
|
||||||
|
endif(ENABLE_HLSL)
|
||||||
add_subdirectory(gtests)
|
add_subdirectory(gtests)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# Suppress all warnings from external projects.
|
# Suppress all warnings from external projects.
|
||||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS -w)
|
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS -w)
|
||||||
|
|
||||||
if (TARGET gmock)
|
if(BUILD_TESTING)
|
||||||
|
if(TARGET gmock)
|
||||||
message(STATUS "Google Mock already configured - use it")
|
message(STATUS "Google Mock already configured - use it")
|
||||||
elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
||||||
# We need to make sure Google Test does not mess up with the
|
# We need to make sure Google Test does not mess up with the
|
||||||
# global CRT settings on Windows.
|
# global CRT settings on Windows.
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -14,8 +15,7 @@ elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
||||||
gtest
|
gtest
|
||||||
gtest_main
|
gtest_main
|
||||||
gmock
|
gmock
|
||||||
gmock_main
|
gmock_main)
|
||||||
)
|
|
||||||
foreach(target ${GTEST_TARGETS})
|
foreach(target ${GTEST_TARGETS})
|
||||||
set_property(TARGET ${target} PROPERTY FOLDER gtest)
|
set_property(TARGET ${target} PROPERTY FOLDER gtest)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
@ -28,7 +28,16 @@ elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
||||||
gtest_disable_pthreads
|
gtest_disable_pthreads
|
||||||
gtest_force_shared_crt
|
gtest_force_shared_crt
|
||||||
gtest_hide_internal_symbols)
|
gtest_hide_internal_symbols)
|
||||||
else()
|
else()
|
||||||
message(STATUS
|
message(STATUS
|
||||||
"Google Mock was not found - tests based on that will not build")
|
"Google Mock was not found - tests based on that will not build")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_OPT AND NOT TARGET SPIRV-Tools-opt)
|
||||||
|
if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/spirv-tools)
|
||||||
|
set(SPIRV_SKIP_TESTS ON CACHE BOOL "Skip building SPIRV-Tools tests")
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/spirv-tools spirv-tools)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,13 @@ set(SOURCES InitializeDll.cpp InitializeDll.h)
|
||||||
|
|
||||||
add_library(OGLCompiler STATIC ${SOURCES})
|
add_library(OGLCompiler STATIC ${SOURCES})
|
||||||
set_property(TARGET OGLCompiler PROPERTY FOLDER glslang)
|
set_property(TARGET OGLCompiler PROPERTY FOLDER glslang)
|
||||||
|
set_property(TARGET OGLCompiler PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
source_group("Source" FILES ${SOURCES})
|
source_group("Source" FILES ${SOURCES})
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
install(TARGETS OGLCompiler
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
ARCHIVE DESTINATION lib)
|
install(TARGETS OGLCompiler
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif(ENABLE_GLSLANG_INSTALL)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,33 +18,37 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define SH_EXPORTING
|
#define SH_EXPORTING
|
||||||
|
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
|
|
||||||
#include "InitializeDll.h"
|
#include "InitializeDll.h"
|
||||||
#include "../glslang/Include/InitializeGlobals.h"
|
#include "../glslang/Include/InitializeGlobals.h"
|
||||||
|
|
||||||
#include "../glslang/Public/ShaderLang.h"
|
#include "../glslang/Public/ShaderLang.h"
|
||||||
|
#include "../glslang/Include/PoolAlloc.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||||
|
|
||||||
|
// Per-process initialization.
|
||||||
|
// Needs to be called at least once before parsing, etc. is done.
|
||||||
|
// Will also do thread initialization for the calling thread; other
|
||||||
|
// threads will need to do that explicitly.
|
||||||
bool InitProcess()
|
bool InitProcess()
|
||||||
{
|
{
|
||||||
glslang::GetGlobalLock();
|
glslang::GetGlobalLock();
|
||||||
|
@ -85,7 +89,9 @@ bool InitProcess()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Per-thread scoped initialization.
|
||||||
|
// Must be called at least once by each new thread sharing the
|
||||||
|
// symbol tables, etc., needed to parse.
|
||||||
bool InitThread()
|
bool InitThread()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -99,17 +105,21 @@ bool InitThread()
|
||||||
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
|
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
InitializeMemoryPools();
|
|
||||||
|
|
||||||
if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
||||||
assert(0 && "InitThread(): Unable to set init flag.");
|
assert(0 && "InitThread(): Unable to set init flag.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glslang::SetThreadPoolAllocator(nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not necessary to call this: InitThread() is reentrant, and the need
|
||||||
|
// to do per thread tear down has been removed.
|
||||||
|
//
|
||||||
|
// This is kept, with memory management removed, to satisfy any exiting
|
||||||
|
// calls to it that rely on it.
|
||||||
bool DetachThread()
|
bool DetachThread()
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
@ -125,14 +135,18 @@ bool DetachThread()
|
||||||
assert(0 && "DetachThread(): Unable to clear init flag.");
|
assert(0 && "DetachThread(): Unable to clear init flag.");
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeGlobalPools();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not necessary to call this: InitProcess() is reentrant.
|
||||||
|
//
|
||||||
|
// This is kept, with memory management removed, to satisfy any exiting
|
||||||
|
// calls to it that rely on it.
|
||||||
|
//
|
||||||
|
// Users of glslang should call shFinalize() or glslang::FinalizeProcess() for
|
||||||
|
// process-scoped memory tear down.
|
||||||
bool DetachProcess()
|
bool DetachProcess()
|
||||||
{
|
{
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
@ -140,12 +154,8 @@ bool DetachProcess()
|
||||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
ShFinalize();
|
|
||||||
|
|
||||||
success = DetachThread();
|
success = DetachThread();
|
||||||
|
|
||||||
FreePoolIndex();
|
|
||||||
|
|
||||||
OS_FreeTLSIndex(ThreadInitializeIndex);
|
OS_FreeTLSIndex(ThreadInitializeIndex);
|
||||||
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,31 +18,30 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
#ifndef __INITIALIZEDLL_H
|
#ifndef __INITIALIZEDLL_H
|
||||||
#define __INITIALIZEDLL_H
|
#define __INITIALIZEDLL_H
|
||||||
|
|
||||||
|
|
||||||
#include "../glslang/OSDependent/osinclude.h"
|
#include "../glslang/OSDependent/osinclude.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
bool InitProcess();
|
bool InitProcess();
|
||||||
bool InitThread();
|
bool InitThread();
|
||||||
bool DetachThread();
|
bool DetachThread(); // not called from standalone, perhaps other tools rely on parts of it
|
||||||
bool DetachProcess();
|
bool DetachProcess(); // not called from standalone, perhaps other tools rely on parts of it
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ options. See REMAPPING AND OPTIMIZATION OPTIONS.
|
||||||
On error, the function supplied to registerErrorHandler() will be invoked.
|
On error, the function supplied to registerErrorHandler() will be invoked.
|
||||||
This can be a standard C/C++ function, a lambda function, or a functor.
|
This can be a standard C/C++ function, a lambda function, or a functor.
|
||||||
The default handler simply calls exit(5); The error handler is a static
|
The default handler simply calls exit(5); The error handler is a static
|
||||||
members, so need only be set up once, not once per spirvbin_t instance.
|
member, so need only be set up once, not once per spirvbin_t instance.
|
||||||
|
|
||||||
Log messages are supplied to registerLogHandler(). By default, log
|
Log messages are supplied to registerLogHandler(). By default, log
|
||||||
messages are eaten silently. The log handler is also a static member.
|
messages are eaten silently. The log handler is also a static member.
|
||||||
|
|
|
@ -13,12 +13,15 @@ glslang
|
||||||
|
|
||||||
An OpenGL and OpenGL ES shader front end and validator.
|
An OpenGL and OpenGL ES shader front end and validator.
|
||||||
|
|
||||||
There are two components:
|
There are several components:
|
||||||
|
|
||||||
1. A front-end library for programmatic parsing of GLSL/ESSL into an AST.
|
1. A GLSL/ESSL front-end for reference validation and translation of GLSL/ESSL into an AST.
|
||||||
|
|
||||||
2. A standalone wrapper, `glslangValidator`, that can be used as a shader
|
2. An HLSL front-end for translation of a broad generic HLL into the AST. See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
|
||||||
validation tool.
|
|
||||||
|
3. A SPIR-V back end for translating the AST to SPIR-V.
|
||||||
|
|
||||||
|
4. A standalone wrapper, `glslangValidator`, that can be used as a command-line tool for the above.
|
||||||
|
|
||||||
How to add a feature protected by a version/extension/stage/profile: See the
|
How to add a feature protected by a version/extension/stage/profile: See the
|
||||||
comment in `glslang/MachineIndependent/Versions.cpp`.
|
comment in `glslang/MachineIndependent/Versions.cpp`.
|
||||||
|
@ -46,49 +49,80 @@ There is also a non-shader extension
|
||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
Instead of building manually, you can also download the binaries for your
|
||||||
|
platform directly from the [master-tot release][master-tot-release] on GitHub.
|
||||||
|
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
|
### Dependencies
|
||||||
|
|
||||||
|
* A C++11 compiler.
|
||||||
|
(For MSVS: 2015 is recommended, 2013 is fully supported/tested, and 2010 support is attempted, but not tested.)
|
||||||
* [CMake][cmake]: for generating compilation targets.
|
* [CMake][cmake]: for generating compilation targets.
|
||||||
|
* make: _Linux_, ninja is an alternative, if configured.
|
||||||
|
* [Python 2.7][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools.)
|
||||||
* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
|
* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
|
||||||
* [googletest][googletest]: _optional_, but should use if making any changes to glslang.
|
* [googletest][googletest]: _optional_, but should use if making any changes to glslang.
|
||||||
|
|
||||||
### Build steps
|
### Build steps
|
||||||
|
|
||||||
#### 1) Check-Out External Projects
|
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
|
```bash
|
||||||
cd <the directory glslang was cloned to, External will be a subdirectory>
|
cd <parent of where you want glslang to be>
|
||||||
|
git clone https://github.com/KhronosGroup/glslang.git
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2) Check-Out External Projects
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd <the directory glslang was cloned to, "External" will be a subdirectory>
|
||||||
git clone https://github.com/google/googletest.git External/googletest
|
git clone https://github.com/google/googletest.git External/googletest
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2) Configure
|
If you wish to assure that SPIR-V generated from HLSL is legal for Vulkan,
|
||||||
|
or wish to invoke -Os to reduce SPIR-V size from HLSL or GLSL, install
|
||||||
Assume the source directory is `$SOURCE_DIR` and
|
spirv-tools with this:
|
||||||
the build directory is `$BUILD_DIR`:
|
|
||||||
|
|
||||||
For building on Linux (assuming using the Ninja generator):
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd $BUILD_DIR
|
./update_glslang_sources.py
|
||||||
|
```
|
||||||
|
|
||||||
cmake -GNinja -DCMAKE_BUILD_TYPE={Debug|Release|RelWithDebInfo} \
|
#### 3) Configure
|
||||||
-DCMAKE_INSTALL_PREFIX=`pwd`/install $SOURCE_DIR
|
|
||||||
|
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={Debug|Release|RelWithDebInfo} \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR
|
||||||
```
|
```
|
||||||
|
|
||||||
For building on Windows:
|
For building on Windows:
|
||||||
|
|
||||||
```bash
|
```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_INSTALL_PREFIX part is for testing (explained later).
|
||||||
```
|
```
|
||||||
|
|
||||||
The CMake GUI also works for Windows (version 3.4.1 tested).
|
The CMake GUI also works for Windows (version 3.4.1 tested).
|
||||||
|
|
||||||
#### 3) Build and Install
|
#### 4) Build and Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# for Linux:
|
# for Linux:
|
||||||
ninja install
|
make -j4 install
|
||||||
|
|
||||||
# for Windows:
|
# for Windows:
|
||||||
cmake --build . --config {Release|Debug|MinSizeRel|RelWithDebInfo} \
|
cmake --build . --config {Release|Debug|MinSizeRel|RelWithDebInfo} \
|
||||||
|
@ -207,8 +241,11 @@ bool InitializeProcess();
|
||||||
void FinalizeProcess();
|
void FinalizeProcess();
|
||||||
|
|
||||||
class TShader
|
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(...);
|
bool parse(...);
|
||||||
void setStrings(...);
|
|
||||||
const char* getInfoLog();
|
const char* getInfoLog();
|
||||||
|
|
||||||
class TProgram
|
class TProgram
|
||||||
|
@ -288,6 +325,8 @@ Basic Internal Operation
|
||||||
|
|
||||||
|
|
||||||
[cmake]: https://cmake.org/
|
[cmake]: https://cmake.org/
|
||||||
|
[python]: https://www.python.org/
|
||||||
[bison]: https://www.gnu.org/software/bison/
|
[bison]: https://www.gnu.org/software/bison/
|
||||||
[googletest]: https://github.com/google/googletest
|
[googletest]: https://github.com/google/googletest
|
||||||
[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
|
[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
|
||||||
|
[master-tot-release]: https://github.com/KhronosGroup/glslang/releases/tag/master-tot
|
||||||
|
|
|
@ -3,27 +3,81 @@ set(SOURCES
|
||||||
InReadableOrder.cpp
|
InReadableOrder.cpp
|
||||||
Logger.cpp
|
Logger.cpp
|
||||||
SpvBuilder.cpp
|
SpvBuilder.cpp
|
||||||
SPVRemapper.cpp
|
|
||||||
doc.cpp
|
doc.cpp
|
||||||
disassemble.cpp)
|
disassemble.cpp)
|
||||||
|
|
||||||
|
set(SPVREMAP_SOURCES
|
||||||
|
SPVRemapper.cpp
|
||||||
|
doc.cpp)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
|
bitutils.h
|
||||||
spirv.hpp
|
spirv.hpp
|
||||||
GLSL.std.450.h
|
GLSL.std.450.h
|
||||||
|
GLSL.ext.EXT.h
|
||||||
|
GLSL.ext.KHR.h
|
||||||
GlslangToSpv.h
|
GlslangToSpv.h
|
||||||
|
hex_float.h
|
||||||
Logger.h
|
Logger.h
|
||||||
SpvBuilder.h
|
SpvBuilder.h
|
||||||
SPVRemapper.h
|
|
||||||
spvIR.h
|
spvIR.h
|
||||||
doc.h
|
doc.h
|
||||||
disassemble.h)
|
disassemble.h)
|
||||||
|
|
||||||
add_library(SPIRV STATIC ${SOURCES} ${HEADERS})
|
set(SPVREMAP_HEADERS
|
||||||
|
SPVRemapper.h
|
||||||
|
doc.h)
|
||||||
|
|
||||||
|
if(ENABLE_AMD_EXTENSIONS)
|
||||||
|
list(APPEND
|
||||||
|
HEADERS
|
||||||
|
GLSL.ext.AMD.h)
|
||||||
|
endif(ENABLE_AMD_EXTENSIONS)
|
||||||
|
|
||||||
|
if(ENABLE_NV_EXTENSIONS)
|
||||||
|
list(APPEND
|
||||||
|
HEADERS
|
||||||
|
GLSL.ext.NV.h)
|
||||||
|
endif(ENABLE_NV_EXTENSIONS)
|
||||||
|
|
||||||
|
add_library(SPIRV ${LIB_TYPE} ${SOURCES} ${HEADERS})
|
||||||
set_property(TARGET SPIRV PROPERTY FOLDER glslang)
|
set_property(TARGET SPIRV PROPERTY FOLDER glslang)
|
||||||
|
set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
target_include_directories(SPIRV PUBLIC ..)
|
||||||
|
|
||||||
|
add_library(SPVRemapper ${LIB_TYPE} ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||||
|
set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
|
||||||
|
set_property(TARGET SPVRemapper PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||||
|
set_target_properties(SPIRV PROPERTIES PREFIX "")
|
||||||
|
set_target_properties(SPVRemapper PROPERTIES PREFIX "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_OPT)
|
||||||
|
target_include_directories(SPIRV
|
||||||
|
PRIVATE ${spirv-tools_SOURCE_DIR}/include
|
||||||
|
PRIVATE ${spirv-tools_SOURCE_DIR}/source
|
||||||
|
)
|
||||||
|
target_link_libraries(SPIRV glslang SPIRV-Tools-opt)
|
||||||
|
else()
|
||||||
|
target_link_libraries(SPIRV glslang)
|
||||||
|
endif(ENABLE_OPT)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
||||||
|
source_group("Source" FILES ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
install(TARGETS SPIRV
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
ARCHIVE DESTINATION lib)
|
if(BUILD_SHARED_LIBS)
|
||||||
|
install(TARGETS SPIRV SPVRemapper
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
else()
|
||||||
|
install(TARGETS SPIRV SPVRemapper
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SPIRV/)
|
||||||
|
endif(ENABLE_GLSLANG_INSTALL)
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextAMD_H
|
||||||
|
#define GLSLextAMD_H
|
||||||
|
|
||||||
|
static const int GLSLextAMDVersion = 100;
|
||||||
|
static const int GLSLextAMDRevision = 7;
|
||||||
|
|
||||||
|
// SPV_AMD_shader_ballot
|
||||||
|
static const char* const E_SPV_AMD_shader_ballot = "SPV_AMD_shader_ballot";
|
||||||
|
|
||||||
|
enum ShaderBallotAMD {
|
||||||
|
ShaderBallotBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
SwizzleInvocationsAMD = 1,
|
||||||
|
SwizzleInvocationsMaskedAMD = 2,
|
||||||
|
WriteInvocationAMD = 3,
|
||||||
|
MbcntAMD = 4,
|
||||||
|
|
||||||
|
ShaderBallotCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_shader_trinary_minmax
|
||||||
|
static const char* const E_SPV_AMD_shader_trinary_minmax = "SPV_AMD_shader_trinary_minmax";
|
||||||
|
|
||||||
|
enum ShaderTrinaryMinMaxAMD {
|
||||||
|
ShaderTrinaryMinMaxBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
FMin3AMD = 1,
|
||||||
|
UMin3AMD = 2,
|
||||||
|
SMin3AMD = 3,
|
||||||
|
FMax3AMD = 4,
|
||||||
|
UMax3AMD = 5,
|
||||||
|
SMax3AMD = 6,
|
||||||
|
FMid3AMD = 7,
|
||||||
|
UMid3AMD = 8,
|
||||||
|
SMid3AMD = 9,
|
||||||
|
|
||||||
|
ShaderTrinaryMinMaxCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_shader_explicit_vertex_parameter
|
||||||
|
static const char* const E_SPV_AMD_shader_explicit_vertex_parameter = "SPV_AMD_shader_explicit_vertex_parameter";
|
||||||
|
|
||||||
|
enum ShaderExplicitVertexParameterAMD {
|
||||||
|
ShaderExplicitVertexParameterBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
InterpolateAtVertexAMD = 1,
|
||||||
|
|
||||||
|
ShaderExplicitVertexParameterCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_gcn_shader
|
||||||
|
static const char* const E_SPV_AMD_gcn_shader = "SPV_AMD_gcn_shader";
|
||||||
|
|
||||||
|
enum GcnShaderAMD {
|
||||||
|
GcnShaderBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
CubeFaceIndexAMD = 1,
|
||||||
|
CubeFaceCoordAMD = 2,
|
||||||
|
TimeAMD = 3,
|
||||||
|
|
||||||
|
GcnShaderCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_gpu_shader_half_float
|
||||||
|
static const char* const E_SPV_AMD_gpu_shader_half_float = "SPV_AMD_gpu_shader_half_float";
|
||||||
|
|
||||||
|
// SPV_AMD_texture_gather_bias_lod
|
||||||
|
static const char* const E_SPV_AMD_texture_gather_bias_lod = "SPV_AMD_texture_gather_bias_lod";
|
||||||
|
|
||||||
|
// SPV_AMD_gpu_shader_int16
|
||||||
|
static const char* const E_SPV_AMD_gpu_shader_int16 = "SPV_AMD_gpu_shader_int16";
|
||||||
|
|
||||||
|
// SPV_AMD_shader_image_load_store_lod
|
||||||
|
static const char* const E_SPV_AMD_shader_image_load_store_lod = "SPV_AMD_shader_image_load_store_lod";
|
||||||
|
|
||||||
|
// SPV_AMD_shader_fragment_mask
|
||||||
|
static const char* const E_SPV_AMD_shader_fragment_mask = "SPV_AMD_shader_fragment_mask";
|
||||||
|
|
||||||
|
// SPV_AMD_gpu_shader_half_float_fetch
|
||||||
|
static const char* const E_SPV_AMD_gpu_shader_half_float_fetch = "SPV_AMD_gpu_shader_half_float_fetch";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextAMD_H
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextEXT_H
|
||||||
|
#define GLSLextEXT_H
|
||||||
|
|
||||||
|
static const int GLSLextEXTVersion = 100;
|
||||||
|
static const int GLSLextEXTRevision = 1;
|
||||||
|
|
||||||
|
static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shader_stencil_export";
|
||||||
|
static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer";
|
||||||
|
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextEXT_H
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextKHR_H
|
||||||
|
#define GLSLextKHR_H
|
||||||
|
|
||||||
|
static const int GLSLextKHRVersion = 100;
|
||||||
|
static const int GLSLextKHRRevision = 2;
|
||||||
|
|
||||||
|
static const char* const E_SPV_KHR_shader_ballot = "SPV_KHR_shader_ballot";
|
||||||
|
static const char* const E_SPV_KHR_subgroup_vote = "SPV_KHR_subgroup_vote";
|
||||||
|
static const char* const E_SPV_KHR_device_group = "SPV_KHR_device_group";
|
||||||
|
static const char* const E_SPV_KHR_multiview = "SPV_KHR_multiview";
|
||||||
|
static const char* const E_SPV_KHR_shader_draw_parameters = "SPV_KHR_shader_draw_parameters";
|
||||||
|
static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit_storage";
|
||||||
|
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
|
||||||
|
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextKHR_H
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2017 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextNV_H
|
||||||
|
#define GLSLextNV_H
|
||||||
|
|
||||||
|
enum BuiltIn;
|
||||||
|
enum Decoration;
|
||||||
|
enum Op;
|
||||||
|
enum Capability;
|
||||||
|
|
||||||
|
static const int GLSLextNVVersion = 100;
|
||||||
|
static const int GLSLextNVRevision = 5;
|
||||||
|
|
||||||
|
//SPV_NV_sample_mask_override_coverage
|
||||||
|
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
||||||
|
|
||||||
|
//SPV_NV_geometry_shader_passthrough
|
||||||
|
const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
|
||||||
|
|
||||||
|
//SPV_NV_viewport_array2
|
||||||
|
const char* const E_SPV_NV_viewport_array2 = "SPV_NV_viewport_array2";
|
||||||
|
const char* const E_ARB_shader_viewport_layer_array = "SPV_ARB_shader_viewport_layer_array";
|
||||||
|
|
||||||
|
//SPV_NV_stereo_view_rendering
|
||||||
|
const char* const E_SPV_NV_stereo_view_rendering = "SPV_NV_stereo_view_rendering";
|
||||||
|
|
||||||
|
//SPV_NVX_multiview_per_view_attributes
|
||||||
|
const char* const E_SPV_NVX_multiview_per_view_attributes = "SPV_NVX_multiview_per_view_attributes";
|
||||||
|
|
||||||
|
//SPV_NV_shader_subgroup_partitioned
|
||||||
|
const char* const E_SPV_NV_shader_subgroup_partitioned = "SPV_NV_shader_subgroup_partitioned";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextNV_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2014 LunarG, Inc.
|
// Copyright (C) 2014 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,24 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
|
#pragma warning(disable : 4464) // relative include path contains '..'
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../glslang/Include/intermediate.h"
|
#include "../glslang/Include/intermediate.h"
|
||||||
|
|
||||||
|
@ -41,10 +47,21 @@
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
struct SpvOptions {
|
||||||
|
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
||||||
|
optimizeSize(false) { }
|
||||||
|
bool generateDebugInfo;
|
||||||
|
bool disableOptimizer;
|
||||||
|
bool optimizeSize;
|
||||||
|
};
|
||||||
|
|
||||||
void GetSpirvVersion(std::string&);
|
void GetSpirvVersion(std::string&);
|
||||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv);
|
int GetSpirvGeneratorVersion();
|
||||||
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger);
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
SpvOptions* options = nullptr);
|
||||||
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
|
||||||
void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
|
void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
|
||||||
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName);
|
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2016 Google, Inc.
|
// Copyright (C) 2016 Google, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// The SPIR-V spec requires code blocks to appear in an order satisfying the
|
// The SPIR-V spec requires code blocks to appear in an order satisfying the
|
||||||
// dominator-tree direction (ie, dominator before the dominated). This is,
|
// dominator-tree direction (ie, dominator before the dominated). This is,
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
#include "spvIR.h"
|
#include "spvIR.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <unordered_map>
|
#include <unordered_set>
|
||||||
|
|
||||||
using spv::Block;
|
using spv::Block;
|
||||||
using spv::Id;
|
using spv::Id;
|
||||||
|
@ -69,33 +69,33 @@ public:
|
||||||
void visit(Block* block)
|
void visit(Block* block)
|
||||||
{
|
{
|
||||||
assert(block);
|
assert(block);
|
||||||
if (visited_[block] || delayed_[block])
|
if (visited_.count(block) || delayed_.count(block))
|
||||||
return;
|
return;
|
||||||
callback_(block);
|
callback_(block);
|
||||||
visited_[block] = true;
|
visited_.insert(block);
|
||||||
Block* mergeBlock = nullptr;
|
Block* mergeBlock = nullptr;
|
||||||
Block* continueBlock = nullptr;
|
Block* continueBlock = nullptr;
|
||||||
auto mergeInst = block->getMergeInstruction();
|
auto mergeInst = block->getMergeInstruction();
|
||||||
if (mergeInst) {
|
if (mergeInst) {
|
||||||
Id mergeId = mergeInst->getIdOperand(0);
|
Id mergeId = mergeInst->getIdOperand(0);
|
||||||
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
|
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
|
||||||
delayed_[mergeBlock] = true;
|
delayed_.insert(mergeBlock);
|
||||||
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
|
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
|
||||||
Id continueId = mergeInst->getIdOperand(1);
|
Id continueId = mergeInst->getIdOperand(1);
|
||||||
continueBlock =
|
continueBlock =
|
||||||
block->getParent().getParent().getInstruction(continueId)->getBlock();
|
block->getParent().getParent().getInstruction(continueId)->getBlock();
|
||||||
delayed_[continueBlock] = true;
|
delayed_.insert(continueBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto successors = block->getSuccessors();
|
const auto successors = block->getSuccessors();
|
||||||
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
||||||
visit(*it);
|
visit(*it);
|
||||||
if (continueBlock) {
|
if (continueBlock) {
|
||||||
delayed_[continueBlock] = false;
|
delayed_.erase(continueBlock);
|
||||||
visit(continueBlock);
|
visit(continueBlock);
|
||||||
}
|
}
|
||||||
if (mergeBlock) {
|
if (mergeBlock) {
|
||||||
delayed_[mergeBlock] = false;
|
delayed_.erase(mergeBlock);
|
||||||
visit(mergeBlock);
|
visit(mergeBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ public:
|
||||||
private:
|
private:
|
||||||
std::function<void(Block*)> callback_;
|
std::function<void(Block*)> callback_;
|
||||||
// Whether a block has already been visited or is being delayed.
|
// Whether a block has already been visited or is being delayed.
|
||||||
std::unordered_map<Block *, bool> visited_, delayed_;
|
std::unordered_set<Block *> visited_, delayed_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2015 LunarG, Inc.
|
// Copyright (C) 2015 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "SPVRemapper.h"
|
#include "SPVRemapper.h"
|
||||||
|
@ -127,6 +127,38 @@ namespace spv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the size of a type in 32-bit words. This currently only
|
||||||
|
// handles ints and floats, and is only invoked by queries which must be
|
||||||
|
// integer types. If ever needed, it can be generalized.
|
||||||
|
unsigned spirvbin_t::typeSizeInWords(spv::Id id) const
|
||||||
|
{
|
||||||
|
const unsigned typeStart = idPos(id);
|
||||||
|
const spv::Op opCode = asOpCode(typeStart);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (opCode) {
|
||||||
|
case spv::OpTypeInt: // fall through...
|
||||||
|
case spv::OpTypeFloat: return (spv[typeStart+2]+31)/32;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Looks up the type of a given const or variable ID, and
|
||||||
|
// returns its size in 32-bit words.
|
||||||
|
unsigned spirvbin_t::idTypeSizeInWords(spv::Id id) const
|
||||||
|
{
|
||||||
|
const auto tid_it = idTypeSizeMap.find(id);
|
||||||
|
if (tid_it == idTypeSizeMap.end()) {
|
||||||
|
error("type size for ID not found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tid_it->second;
|
||||||
|
}
|
||||||
|
|
||||||
// Is this an opcode we should remove when using --strip?
|
// Is this an opcode we should remove when using --strip?
|
||||||
bool spirvbin_t::isStripOp(spv::Op opCode) const
|
bool spirvbin_t::isStripOp(spv::Op opCode) const
|
||||||
{
|
{
|
||||||
|
@ -140,6 +172,7 @@ namespace spv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if this opcode is flow control
|
||||||
bool spirvbin_t::isFlowCtrl(spv::Op opCode) const
|
bool spirvbin_t::isFlowCtrl(spv::Op opCode) const
|
||||||
{
|
{
|
||||||
switch (opCode) {
|
switch (opCode) {
|
||||||
|
@ -155,6 +188,7 @@ namespace spv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if this opcode defines a type
|
||||||
bool spirvbin_t::isTypeOp(spv::Op opCode) const
|
bool spirvbin_t::isTypeOp(spv::Op opCode) const
|
||||||
{
|
{
|
||||||
switch (opCode) {
|
switch (opCode) {
|
||||||
|
@ -182,17 +216,23 @@ namespace spv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if this opcode defines a constant
|
||||||
bool spirvbin_t::isConstOp(spv::Op opCode) const
|
bool spirvbin_t::isConstOp(spv::Op opCode) const
|
||||||
{
|
{
|
||||||
switch (opCode) {
|
switch (opCode) {
|
||||||
case spv::OpConstantNull: error("unimplemented constant type");
|
case spv::OpConstantNull:
|
||||||
case spv::OpConstantSampler: error("unimplemented constant type");
|
case spv::OpConstantSampler:
|
||||||
|
error("unimplemented constant type");
|
||||||
|
return true;
|
||||||
|
|
||||||
case spv::OpConstantTrue:
|
case spv::OpConstantTrue:
|
||||||
case spv::OpConstantFalse:
|
case spv::OpConstantFalse:
|
||||||
case spv::OpConstantComposite:
|
case spv::OpConstantComposite:
|
||||||
case spv::OpConstant: return true;
|
case spv::OpConstant:
|
||||||
default: return false;
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,21 +256,33 @@ namespace spv {
|
||||||
|
|
||||||
spv::Id spirvbin_t::localId(spv::Id id, spv::Id newId)
|
spv::Id spirvbin_t::localId(spv::Id id, spv::Id newId)
|
||||||
{
|
{
|
||||||
assert(id != spv::NoResult && newId != spv::NoResult);
|
//assert(id != spv::NoResult && newId != spv::NoResult);
|
||||||
|
|
||||||
|
if (id > bound()) {
|
||||||
|
error(std::string("ID out of range: ") + std::to_string(id));
|
||||||
|
return spirvbin_t::unused;
|
||||||
|
}
|
||||||
|
|
||||||
if (id >= idMapL.size())
|
if (id >= idMapL.size())
|
||||||
idMapL.resize(id+1, unused);
|
idMapL.resize(id+1, unused);
|
||||||
|
|
||||||
if (newId != unmapped && newId != unused) {
|
if (newId != unmapped && newId != unused) {
|
||||||
if (isOldIdUnused(id))
|
if (isOldIdUnused(id)) {
|
||||||
error(std::string("ID unused in module: ") + std::to_string(id));
|
error(std::string("ID unused in module: ") + std::to_string(id));
|
||||||
|
return spirvbin_t::unused;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isOldIdUnmapped(id))
|
if (!isOldIdUnmapped(id)) {
|
||||||
error(std::string("ID already mapped: ") + std::to_string(id) + " -> "
|
error(std::string("ID already mapped: ") + std::to_string(id) + " -> "
|
||||||
+ std::to_string(localId(id)));
|
+ std::to_string(localId(id)));
|
||||||
|
|
||||||
if (isNewIdMapped(newId))
|
return spirvbin_t::unused;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNewIdMapped(newId)) {
|
||||||
error(std::string("ID already used in module: ") + std::to_string(newId));
|
error(std::string("ID already used in module: ") + std::to_string(newId));
|
||||||
|
return spirvbin_t::unused;
|
||||||
|
}
|
||||||
|
|
||||||
msg(4, 4, std::string("map: ") + std::to_string(id) + " -> " + std::to_string(newId));
|
msg(4, 4, std::string("map: ") + std::to_string(id) + " -> " + std::to_string(newId));
|
||||||
setMapped(newId);
|
setMapped(newId);
|
||||||
|
@ -256,7 +308,6 @@ namespace spv {
|
||||||
return literal;
|
return literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void spirvbin_t::applyMap()
|
void spirvbin_t::applyMap()
|
||||||
{
|
{
|
||||||
msg(3, 2, std::string("Applying map: "));
|
msg(3, 2, std::string("Applying map: "));
|
||||||
|
@ -265,12 +316,15 @@ namespace spv {
|
||||||
process(inst_fn_nop, // ignore instructions
|
process(inst_fn_nop, // ignore instructions
|
||||||
[this](spv::Id& id) {
|
[this](spv::Id& id) {
|
||||||
id = localId(id);
|
id = localId(id);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
assert(id != unused && id != unmapped);
|
assert(id != unused && id != unmapped);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Find free IDs for anything we haven't mapped
|
// Find free IDs for anything we haven't mapped
|
||||||
void spirvbin_t::mapRemainder()
|
void spirvbin_t::mapRemainder()
|
||||||
{
|
{
|
||||||
|
@ -284,25 +338,31 @@ namespace spv {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Find a new mapping for any used but unmapped IDs
|
// Find a new mapping for any used but unmapped IDs
|
||||||
if (isOldIdUnmapped(id))
|
if (isOldIdUnmapped(id)) {
|
||||||
localId(id, unusedId = nextUnusedId(unusedId));
|
localId(id, unusedId = nextUnusedId(unusedId));
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isOldIdUnmapped(id))
|
if (isOldIdUnmapped(id)) {
|
||||||
error(std::string("old ID not mapped: ") + std::to_string(id));
|
error(std::string("old ID not mapped: ") + std::to_string(id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Track max bound
|
// Track max bound
|
||||||
maxBound = std::max(maxBound, localId(id) + 1);
|
maxBound = std::max(maxBound, localId(id) + 1);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bound(maxBound); // reset header ID bound to as big as it now needs to be
|
bound(maxBound); // reset header ID bound to as big as it now needs to be
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark debug instructions for stripping
|
||||||
void spirvbin_t::stripDebug()
|
void spirvbin_t::stripDebug()
|
||||||
{
|
{
|
||||||
if ((options & STRIP) == 0)
|
// Strip instructions in the stripOp set: debug info.
|
||||||
return;
|
|
||||||
|
|
||||||
// build local Id and name maps
|
|
||||||
process(
|
process(
|
||||||
[&](spv::Op opCode, unsigned start) {
|
[&](spv::Op opCode, unsigned start) {
|
||||||
// remember opcodes we want to strip later
|
// remember opcodes we want to strip later
|
||||||
|
@ -313,6 +373,32 @@ namespace spv {
|
||||||
op_fn_nop);
|
op_fn_nop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark instructions that refer to now-removed IDs for stripping
|
||||||
|
void spirvbin_t::stripDeadRefs()
|
||||||
|
{
|
||||||
|
process(
|
||||||
|
[&](spv::Op opCode, unsigned start) {
|
||||||
|
// strip opcodes pointing to removed data
|
||||||
|
switch (opCode) {
|
||||||
|
case spv::OpName:
|
||||||
|
case spv::OpMemberName:
|
||||||
|
case spv::OpDecorate:
|
||||||
|
case spv::OpMemberDecorate:
|
||||||
|
if (idPosR.find(asId(start+1)) == idPosR.end())
|
||||||
|
stripInst(start);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break; // leave it alone
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
op_fn_nop);
|
||||||
|
|
||||||
|
strip();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update local maps of ID, type, etc positions
|
||||||
void spirvbin_t::buildLocalMaps()
|
void spirvbin_t::buildLocalMaps()
|
||||||
{
|
{
|
||||||
msg(2, 2, std::string("build local maps: "));
|
msg(2, 2, std::string("build local maps: "));
|
||||||
|
@ -321,10 +407,9 @@ namespace spv {
|
||||||
idMapL.clear();
|
idMapL.clear();
|
||||||
// preserve nameMap, so we don't clear that.
|
// preserve nameMap, so we don't clear that.
|
||||||
fnPos.clear();
|
fnPos.clear();
|
||||||
fnPosDCE.clear();
|
|
||||||
fnCalls.clear();
|
fnCalls.clear();
|
||||||
typeConstPos.clear();
|
typeConstPos.clear();
|
||||||
typeConstPosR.clear();
|
idPosR.clear();
|
||||||
entryPoint = spv::NoResult;
|
entryPoint = spv::NoResult;
|
||||||
largestNewId = 0;
|
largestNewId = 0;
|
||||||
|
|
||||||
|
@ -336,9 +421,27 @@ namespace spv {
|
||||||
// build local Id and name maps
|
// build local Id and name maps
|
||||||
process(
|
process(
|
||||||
[&](spv::Op opCode, unsigned start) {
|
[&](spv::Op opCode, unsigned start) {
|
||||||
// remember opcodes we want to strip later
|
unsigned word = start+1;
|
||||||
if ((options & STRIP) && isStripOp(opCode))
|
spv::Id typeId = spv::NoResult;
|
||||||
stripInst(start);
|
|
||||||
|
if (spv::InstructionDesc[opCode].hasType())
|
||||||
|
typeId = asId(word++);
|
||||||
|
|
||||||
|
// If there's a result ID, remember the size of its type
|
||||||
|
if (spv::InstructionDesc[opCode].hasResult()) {
|
||||||
|
const spv::Id resultId = asId(word++);
|
||||||
|
idPosR[resultId] = start;
|
||||||
|
|
||||||
|
if (typeId != spv::NoResult) {
|
||||||
|
const unsigned idTypeSize = typeSizeInWords(typeId);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (idTypeSize != 0)
|
||||||
|
idTypeSizeMap[resultId] = idTypeSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (opCode == spv::Op::OpName) {
|
if (opCode == spv::Op::OpName) {
|
||||||
const spv::Id target = asId(start+1);
|
const spv::Id target = asId(start+1);
|
||||||
|
@ -350,24 +453,31 @@ namespace spv {
|
||||||
} else if (opCode == spv::Op::OpEntryPoint) {
|
} else if (opCode == spv::Op::OpEntryPoint) {
|
||||||
entryPoint = asId(start + 2);
|
entryPoint = asId(start + 2);
|
||||||
} else if (opCode == spv::Op::OpFunction) {
|
} else if (opCode == spv::Op::OpFunction) {
|
||||||
if (fnStart != 0)
|
if (fnStart != 0) {
|
||||||
error("nested function found");
|
error("nested function found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fnStart = start;
|
fnStart = start;
|
||||||
fnRes = asId(start + 2);
|
fnRes = asId(start + 2);
|
||||||
} else if (opCode == spv::Op::OpFunctionEnd) {
|
} else if (opCode == spv::Op::OpFunctionEnd) {
|
||||||
assert(fnRes != spv::NoResult);
|
assert(fnRes != spv::NoResult);
|
||||||
if (fnStart == 0)
|
if (fnStart == 0) {
|
||||||
error("function end without function start");
|
error("function end without function start");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fnPos[fnRes] = range_t(fnStart, start + asWordCount(start));
|
fnPos[fnRes] = range_t(fnStart, start + asWordCount(start));
|
||||||
fnStart = 0;
|
fnStart = 0;
|
||||||
} else if (isConstOp(opCode)) {
|
} else if (isConstOp(opCode)) {
|
||||||
|
if (errorLatch)
|
||||||
|
return false;
|
||||||
|
|
||||||
assert(asId(start + 2) != spv::NoResult);
|
assert(asId(start + 2) != spv::NoResult);
|
||||||
typeConstPos.insert(start);
|
typeConstPos.insert(start);
|
||||||
typeConstPosR[asId(start + 2)] = start;
|
|
||||||
} else if (isTypeOp(opCode)) {
|
} else if (isTypeOp(opCode)) {
|
||||||
assert(asId(start + 1) != spv::NoResult);
|
assert(asId(start + 1) != spv::NoResult);
|
||||||
typeConstPos.insert(start);
|
typeConstPos.insert(start);
|
||||||
typeConstPosR[asId(start + 1)] = start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -382,30 +492,37 @@ namespace spv {
|
||||||
{
|
{
|
||||||
msg(2, 2, std::string("validating: "));
|
msg(2, 2, std::string("validating: "));
|
||||||
|
|
||||||
if (spv.size() < header_size)
|
if (spv.size() < header_size) {
|
||||||
error("file too short: ");
|
error("file too short: ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (magic() != spv::MagicNumber)
|
if (magic() != spv::MagicNumber) {
|
||||||
error("bad magic number");
|
error("bad magic number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// field 1 = version
|
// field 1 = version
|
||||||
// field 2 = generator magic
|
// field 2 = generator magic
|
||||||
// field 3 = result <id> bound
|
// field 3 = result <id> bound
|
||||||
|
|
||||||
if (schemaNum() != 0)
|
if (schemaNum() != 0) {
|
||||||
error("bad schema, must be 0");
|
error("bad schema, must be 0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int spirvbin_t::processInstruction(unsigned word, instfn_t instFn, idfn_t idFn)
|
int spirvbin_t::processInstruction(unsigned word, instfn_t instFn, idfn_t idFn)
|
||||||
{
|
{
|
||||||
const auto instructionStart = word;
|
const auto instructionStart = word;
|
||||||
const unsigned wordCount = asWordCount(instructionStart);
|
const unsigned wordCount = asWordCount(instructionStart);
|
||||||
const spv::Op opCode = asOpCode(instructionStart);
|
|
||||||
const int nextInst = word++ + wordCount;
|
const int nextInst = word++ + wordCount;
|
||||||
|
spv::Op opCode = asOpCode(instructionStart);
|
||||||
|
|
||||||
if (nextInst > int(spv.size()))
|
if (nextInst > int(spv.size())) {
|
||||||
error("spir instruction terminated too early");
|
error("spir instruction terminated too early");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Base for computing number of operands; will be updated as more is learned
|
// Base for computing number of operands; will be updated as more is learned
|
||||||
unsigned numOperands = wordCount - 1;
|
unsigned numOperands = wordCount - 1;
|
||||||
|
@ -436,10 +553,31 @@ namespace spv {
|
||||||
return nextInst;
|
return nextInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Circular buffer so we can look back at previous unmapped values during the mapping pass.
|
||||||
|
static const unsigned idBufferSize = 4;
|
||||||
|
spv::Id idBuffer[idBufferSize];
|
||||||
|
unsigned idBufferPos = 0;
|
||||||
|
|
||||||
// Store IDs from instruction in our map
|
// Store IDs from instruction in our map
|
||||||
for (int op = 0; numOperands > 0; ++op, --numOperands) {
|
for (int op = 0; numOperands > 0; ++op, --numOperands) {
|
||||||
|
// SpecConstantOp is special: it includes the operands of another opcode which is
|
||||||
|
// given as a literal in the 3rd word. We will switch over to pretending that the
|
||||||
|
// opcode being processed is the literal opcode value of the SpecConstantOp. See the
|
||||||
|
// SPIRV spec for details. This way we will handle IDs and literals as appropriate for
|
||||||
|
// the embedded op.
|
||||||
|
if (opCode == spv::OpSpecConstantOp) {
|
||||||
|
if (op == 0) {
|
||||||
|
opCode = asOpCode(word++); // this is the opcode embedded in the SpecConstantOp.
|
||||||
|
--numOperands;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (spv::InstructionDesc[opCode].operands.getClass(op)) {
|
switch (spv::InstructionDesc[opCode].operands.getClass(op)) {
|
||||||
case spv::OperandId:
|
case spv::OperandId:
|
||||||
|
case spv::OperandScope:
|
||||||
|
case spv::OperandMemorySemantics:
|
||||||
|
idBuffer[idBufferPos] = asId(word);
|
||||||
|
idBufferPos = (idBufferPos + 1) % idBufferSize;
|
||||||
idFn(asId(word++));
|
idFn(asId(word++));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -457,13 +595,28 @@ namespace spv {
|
||||||
// word += numOperands;
|
// word += numOperands;
|
||||||
return nextInst;
|
return nextInst;
|
||||||
|
|
||||||
case spv::OperandVariableLiteralId:
|
case spv::OperandVariableLiteralId: {
|
||||||
while (numOperands > 0) {
|
if (opCode == OpSwitch) {
|
||||||
++word; // immediate
|
// word-2 is the position of the selector ID. OpSwitch Literals match its type.
|
||||||
idFn(asId(word++)); // ID
|
// In case the IDs are currently being remapped, we get the word[-2] ID from
|
||||||
numOperands -= 2;
|
// the circular idBuffer.
|
||||||
|
const unsigned literalSizePos = (idBufferPos+idBufferSize-2) % idBufferSize;
|
||||||
|
const unsigned literalSize = idTypeSizeInWords(idBuffer[literalSizePos]);
|
||||||
|
const unsigned numLiteralIdPairs = (nextInst-word) / (1+literalSize);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (unsigned arg=0; arg<numLiteralIdPairs; ++arg) {
|
||||||
|
word += literalSize; // literal
|
||||||
|
idFn(asId(word++)); // label
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
assert(0); // currentely, only OpSwitch uses OperandVariableLiteralId
|
||||||
|
}
|
||||||
|
|
||||||
return nextInst;
|
return nextInst;
|
||||||
|
}
|
||||||
|
|
||||||
case spv::OperandLiteralString: {
|
case spv::OperandLiteralString: {
|
||||||
const int stringWordCount = literalStringWords(literalString(word));
|
const int stringWordCount = literalStringWords(literalString(word));
|
||||||
|
@ -500,9 +653,7 @@ namespace spv {
|
||||||
case spv::OperandSelect:
|
case spv::OperandSelect:
|
||||||
case spv::OperandLoop:
|
case spv::OperandLoop:
|
||||||
case spv::OperandFunction:
|
case spv::OperandFunction:
|
||||||
case spv::OperandMemorySemantics:
|
|
||||||
case spv::OperandMemoryAccess:
|
case spv::OperandMemoryAccess:
|
||||||
case spv::OperandScope:
|
|
||||||
case spv::OperandGroupOperation:
|
case spv::OperandGroupOperation:
|
||||||
case spv::OperandKernelEnqueueFlags:
|
case spv::OperandKernelEnqueueFlags:
|
||||||
case spv::OperandKernelProfilingInfo:
|
case spv::OperandKernelProfilingInfo:
|
||||||
|
@ -532,9 +683,13 @@ namespace spv {
|
||||||
// basic parsing and InstructionDesc table borrowed from SpvDisassemble.cpp...
|
// basic parsing and InstructionDesc table borrowed from SpvDisassemble.cpp...
|
||||||
unsigned nextInst = unsigned(spv.size());
|
unsigned nextInst = unsigned(spv.size());
|
||||||
|
|
||||||
for (unsigned word = begin; word < end; word = nextInst)
|
for (unsigned word = begin; word < end; word = nextInst) {
|
||||||
nextInst = processInstruction(word, instFn, idFn);
|
nextInst = processInstruction(word, instFn, idFn);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,8 +704,11 @@ namespace spv {
|
||||||
for (const char c : name.first)
|
for (const char c : name.first)
|
||||||
hashval = hashval * 1009 + c;
|
hashval = hashval * 1009 + c;
|
||||||
|
|
||||||
if (isOldIdUnmapped(name.second))
|
if (isOldIdUnmapped(name.second)) {
|
||||||
localId(name.second, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
localId(name.second, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,6 +730,9 @@ namespace spv {
|
||||||
[&](spv::Op, unsigned start) { instPos.push_back(start); return true; },
|
[&](spv::Op, unsigned start) { instPos.push_back(start); return true; },
|
||||||
op_fn_nop);
|
op_fn_nop);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
// Window size for context-sensitive canonicalization values
|
// Window size for context-sensitive canonicalization values
|
||||||
// Empirical best size from a single data set. TODO: Would be a good tunable.
|
// Empirical best size from a single data set. TODO: Would be a good tunable.
|
||||||
// We essentially perform a little convolution around each instruction,
|
// We essentially perform a little convolution around each instruction,
|
||||||
|
@ -607,8 +768,12 @@ namespace spv {
|
||||||
hashval = hashval * 30103 + asOpCodeHash(instPos[i]); // 30103 = semiarbitrary prime
|
hashval = hashval * 30103 + asOpCodeHash(instPos[i]); // 30103 = semiarbitrary prime
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOldIdUnmapped(resId))
|
if (isOldIdUnmapped(resId)) {
|
||||||
localId(resId, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
localId(resId, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,6 +866,9 @@ namespace spv {
|
||||||
[&](spv::Id& id) { if (idMap.find(id) != idMap.end()) id = idMap[id]; }
|
[&](spv::Id& id) { if (idMap.find(id) != idMap.end()) id = idMap[id]; }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
// EXPERIMENTAL: Implicit output stores
|
// EXPERIMENTAL: Implicit output stores
|
||||||
fnLocalVars.clear();
|
fnLocalVars.clear();
|
||||||
idMap.clear();
|
idMap.clear();
|
||||||
|
@ -721,11 +889,17 @@ namespace spv {
|
||||||
},
|
},
|
||||||
op_fn_nop);
|
op_fn_nop);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
process(
|
process(
|
||||||
inst_fn_nop,
|
inst_fn_nop,
|
||||||
[&](spv::Id& id) { if (idMap.find(id) != idMap.end()) id = idMap[id]; }
|
[&](spv::Id& id) { if (idMap.find(id) != idMap.end()) id = idMap[id]; }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
strip(); // strip out data we decided to eliminate
|
strip(); // strip out data we decided to eliminate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,6 +999,9 @@ namespace spv {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
process(
|
process(
|
||||||
[&](spv::Op opCode, unsigned start) {
|
[&](spv::Op opCode, unsigned start) {
|
||||||
if (opCode == spv::OpLoad && fnLocalVars.count(asId(start+3)) > 0)
|
if (opCode == spv::OpLoad && fnLocalVars.count(asId(start+3)) > 0)
|
||||||
|
@ -833,6 +1010,9 @@ namespace spv {
|
||||||
},
|
},
|
||||||
op_fn_nop);
|
op_fn_nop);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
// Chase replacements to their origins, in case there is a chain such as:
|
// Chase replacements to their origins, in case there is a chain such as:
|
||||||
// 2 = store 1
|
// 2 = store 1
|
||||||
// 3 = load 2
|
// 3 = load 2
|
||||||
|
@ -866,6 +1046,9 @@ namespace spv {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
strip(); // strip out data we decided to eliminate
|
strip(); // strip out data we decided to eliminate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,7 +1074,6 @@ namespace spv {
|
||||||
if (call_it == fnCalls.end() || call_it->second == 0) {
|
if (call_it == fnCalls.end() || call_it->second == 0) {
|
||||||
changed = true;
|
changed = true;
|
||||||
stripRange.push_back(fn->second);
|
stripRange.push_back(fn->second);
|
||||||
fnPosDCE.insert(*fn);
|
|
||||||
|
|
||||||
// decrease counts of called functions
|
// decrease counts of called functions
|
||||||
process(
|
process(
|
||||||
|
@ -910,6 +1092,9 @@ namespace spv {
|
||||||
fn->second.first,
|
fn->second.first,
|
||||||
fn->second.second);
|
fn->second.second);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
fn = fnPos.erase(fn);
|
fn = fnPos.erase(fn);
|
||||||
} else ++fn;
|
} else ++fn;
|
||||||
}
|
}
|
||||||
|
@ -942,14 +1127,21 @@ namespace spv {
|
||||||
[&](spv::Id& id) { if (varUseCount[id]) ++varUseCount[id]; }
|
[&](spv::Id& id) { if (varUseCount[id]) ++varUseCount[id]; }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
|
||||||
// Remove single-use function variables + associated decorations and names
|
// Remove single-use function variables + associated decorations and names
|
||||||
process(
|
process(
|
||||||
[&](spv::Op opCode, unsigned start) {
|
[&](spv::Op opCode, unsigned start) {
|
||||||
if ((opCode == spv::OpVariable && varUseCount[asId(start+2)] == 1) ||
|
spv::Id id = spv::NoResult;
|
||||||
(opCode == spv::OpDecorate && varUseCount[asId(start+1)] == 1) ||
|
if (opCode == spv::OpVariable)
|
||||||
(opCode == spv::OpName && varUseCount[asId(start+1)] == 1)) {
|
id = asId(start+2);
|
||||||
|
if (opCode == spv::OpDecorate || opCode == spv::OpName)
|
||||||
|
id = asId(start+1);
|
||||||
|
|
||||||
|
if (id != spv::NoResult && varUseCount[id] == 1)
|
||||||
stripInst(start);
|
stripInst(start);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
op_fn_nop);
|
op_fn_nop);
|
||||||
|
@ -966,27 +1158,36 @@ namespace spv {
|
||||||
|
|
||||||
std::unordered_map<spv::Id, int> typeUseCount;
|
std::unordered_map<spv::Id, int> typeUseCount;
|
||||||
|
|
||||||
|
// This is not the most efficient algorithm, but this is an offline tool, and
|
||||||
|
// it's easy to write this way. Can be improved opportunistically if needed.
|
||||||
|
bool changed = true;
|
||||||
|
while (changed) {
|
||||||
|
changed = false;
|
||||||
|
strip();
|
||||||
|
typeUseCount.clear();
|
||||||
|
|
||||||
// Count total type usage
|
// Count total type usage
|
||||||
process(inst_fn_nop,
|
process(inst_fn_nop,
|
||||||
[&](spv::Id& id) { if (isType[id]) ++typeUseCount[id]; }
|
[&](spv::Id& id) { if (isType[id]) ++typeUseCount[id]; }
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove types from deleted code
|
if (errorLatch)
|
||||||
for (const auto& fn : fnPosDCE)
|
return;
|
||||||
process(inst_fn_nop,
|
|
||||||
[&](spv::Id& id) { if (isType[id]) --typeUseCount[id]; },
|
|
||||||
fn.second.first, fn.second.second);
|
|
||||||
|
|
||||||
// Remove single reference types
|
// Remove single reference types
|
||||||
for (const auto typeStart : typeConstPos) {
|
for (const auto typeStart : typeConstPos) {
|
||||||
const spv::Id typeId = asTypeConstId(typeStart);
|
const spv::Id typeId = asTypeConstId(typeStart);
|
||||||
if (typeUseCount[typeId] == 1) {
|
if (typeUseCount[typeId] == 1) {
|
||||||
|
changed = true;
|
||||||
--typeUseCount[typeId];
|
--typeUseCount[typeId];
|
||||||
stripInst(typeStart);
|
stripInst(typeStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NOTDEF
|
#ifdef NOTDEF
|
||||||
bool spirvbin_t::matchType(const spirvbin_t::globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const
|
bool spirvbin_t::matchType(const spirvbin_t::globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const
|
||||||
|
@ -1047,7 +1248,6 @@ namespace spv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Look for an equivalent type in the globalTypes map
|
// Look for an equivalent type in the globalTypes map
|
||||||
spv::Id spirvbin_t::findType(const spirvbin_t::globaltypes_t& globalTypes, spv::Id lt) const
|
spv::Id spirvbin_t::findType(const spirvbin_t::globaltypes_t& globalTypes, spv::Id lt) const
|
||||||
{
|
{
|
||||||
|
@ -1060,12 +1260,14 @@ namespace spv {
|
||||||
}
|
}
|
||||||
#endif // NOTDEF
|
#endif // NOTDEF
|
||||||
|
|
||||||
// Return start position in SPV of given type. error if not found.
|
// Return start position in SPV of given Id. error if not found.
|
||||||
unsigned spirvbin_t::typePos(spv::Id id) const
|
unsigned spirvbin_t::idPos(spv::Id id) const
|
||||||
{
|
{
|
||||||
const auto tid_it = typeConstPosR.find(id);
|
const auto tid_it = idPosR.find(id);
|
||||||
if (tid_it == typeConstPosR.end())
|
if (tid_it == idPosR.end()) {
|
||||||
error("type ID not found");
|
error("ID not found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return tid_it->second;
|
return tid_it->second;
|
||||||
}
|
}
|
||||||
|
@ -1083,11 +1285,11 @@ namespace spv {
|
||||||
case spv::OpTypeInt: return 3 + (spv[typeStart+3]);
|
case spv::OpTypeInt: return 3 + (spv[typeStart+3]);
|
||||||
case spv::OpTypeFloat: return 5;
|
case spv::OpTypeFloat: return 5;
|
||||||
case spv::OpTypeVector:
|
case spv::OpTypeVector:
|
||||||
return 6 + hashType(typePos(spv[typeStart+2])) * (spv[typeStart+3] - 1);
|
return 6 + hashType(idPos(spv[typeStart+2])) * (spv[typeStart+3] - 1);
|
||||||
case spv::OpTypeMatrix:
|
case spv::OpTypeMatrix:
|
||||||
return 30 + hashType(typePos(spv[typeStart+2])) * (spv[typeStart+3] - 1);
|
return 30 + hashType(idPos(spv[typeStart+2])) * (spv[typeStart+3] - 1);
|
||||||
case spv::OpTypeImage:
|
case spv::OpTypeImage:
|
||||||
return 120 + hashType(typePos(spv[typeStart+2])) +
|
return 120 + hashType(idPos(spv[typeStart+2])) +
|
||||||
spv[typeStart+3] + // dimensionality
|
spv[typeStart+3] + // dimensionality
|
||||||
spv[typeStart+4] * 8 * 16 + // depth
|
spv[typeStart+4] * 8 * 16 + // depth
|
||||||
spv[typeStart+5] * 4 * 16 + // arrayed
|
spv[typeStart+5] * 4 * 16 + // arrayed
|
||||||
|
@ -1098,24 +1300,24 @@ namespace spv {
|
||||||
case spv::OpTypeSampledImage:
|
case spv::OpTypeSampledImage:
|
||||||
return 502;
|
return 502;
|
||||||
case spv::OpTypeArray:
|
case spv::OpTypeArray:
|
||||||
return 501 + hashType(typePos(spv[typeStart+2])) * spv[typeStart+3];
|
return 501 + hashType(idPos(spv[typeStart+2])) * spv[typeStart+3];
|
||||||
case spv::OpTypeRuntimeArray:
|
case spv::OpTypeRuntimeArray:
|
||||||
return 5000 + hashType(typePos(spv[typeStart+2]));
|
return 5000 + hashType(idPos(spv[typeStart+2]));
|
||||||
case spv::OpTypeStruct:
|
case spv::OpTypeStruct:
|
||||||
{
|
{
|
||||||
std::uint32_t hash = 10000;
|
std::uint32_t hash = 10000;
|
||||||
for (unsigned w=2; w < wordCount; ++w)
|
for (unsigned w=2; w < wordCount; ++w)
|
||||||
hash += w * hashType(typePos(spv[typeStart+w]));
|
hash += w * hashType(idPos(spv[typeStart+w]));
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
case spv::OpTypeOpaque: return 6000 + spv[typeStart+2];
|
case spv::OpTypeOpaque: return 6000 + spv[typeStart+2];
|
||||||
case spv::OpTypePointer: return 100000 + hashType(typePos(spv[typeStart+3]));
|
case spv::OpTypePointer: return 100000 + hashType(idPos(spv[typeStart+3]));
|
||||||
case spv::OpTypeFunction:
|
case spv::OpTypeFunction:
|
||||||
{
|
{
|
||||||
std::uint32_t hash = 200000;
|
std::uint32_t hash = 200000;
|
||||||
for (unsigned w=2; w < wordCount; ++w)
|
for (unsigned w=2; w < wordCount; ++w)
|
||||||
hash += w * hashType(typePos(spv[typeStart+w]));
|
hash += w * hashType(idPos(spv[typeStart+w]));
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,14 +1334,14 @@ namespace spv {
|
||||||
case spv::OpConstantFalse: return 300008;
|
case spv::OpConstantFalse: return 300008;
|
||||||
case spv::OpConstantComposite:
|
case spv::OpConstantComposite:
|
||||||
{
|
{
|
||||||
std::uint32_t hash = 300011 + hashType(typePos(spv[typeStart+1]));
|
std::uint32_t hash = 300011 + hashType(idPos(spv[typeStart+1]));
|
||||||
for (unsigned w=3; w < wordCount; ++w)
|
for (unsigned w=3; w < wordCount; ++w)
|
||||||
hash += w * hashType(typePos(spv[typeStart+w]));
|
hash += w * hashType(idPos(spv[typeStart+w]));
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
case spv::OpConstant:
|
case spv::OpConstant:
|
||||||
{
|
{
|
||||||
std::uint32_t hash = 400011 + hashType(typePos(spv[typeStart+1]));
|
std::uint32_t hash = 400011 + hashType(idPos(spv[typeStart+1]));
|
||||||
for (unsigned w=3; w < wordCount; ++w)
|
for (unsigned w=3; w < wordCount; ++w)
|
||||||
hash += w * spv[typeStart+w];
|
hash += w * spv[typeStart+w];
|
||||||
return hash;
|
return hash;
|
||||||
|
@ -1164,11 +1366,16 @@ namespace spv {
|
||||||
const spv::Id resId = asTypeConstId(typeStart);
|
const spv::Id resId = asTypeConstId(typeStart);
|
||||||
const std::uint32_t hashval = hashType(typeStart);
|
const std::uint32_t hashval = hashType(typeStart);
|
||||||
|
|
||||||
if (isOldIdUnmapped(resId))
|
if (errorLatch)
|
||||||
localId(resId, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
return;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (isOldIdUnmapped(resId)) {
|
||||||
|
localId(resId, nextUnusedId(hashval % softTypeIdLimit + firstMappedID));
|
||||||
|
if (errorLatch)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Strip a single binary by removing ranges given in stripRange
|
// Strip a single binary by removing ranges given in stripRange
|
||||||
void spirvbin_t::strip()
|
void spirvbin_t::strip()
|
||||||
|
@ -1185,7 +1392,7 @@ namespace spv {
|
||||||
|
|
||||||
int strippedPos = 0;
|
int strippedPos = 0;
|
||||||
for (unsigned word = 0; word < unsigned(spv.size()); ++word) {
|
for (unsigned word = 0; word < unsigned(spv.size()); ++word) {
|
||||||
if (strip_it != stripRange.end() && word >= strip_it->second)
|
while (strip_it != stripRange.end() && word >= strip_it->second)
|
||||||
++strip_it;
|
++strip_it;
|
||||||
|
|
||||||
if (strip_it == stripRange.end() || word < strip_it->first || word >= strip_it->second)
|
if (strip_it == stripRange.end() || word < strip_it->first || word >= strip_it->second)
|
||||||
|
@ -1207,24 +1414,55 @@ namespace spv {
|
||||||
spv::Parameterize();
|
spv::Parameterize();
|
||||||
|
|
||||||
validate(); // validate header
|
validate(); // validate header
|
||||||
buildLocalMaps();
|
buildLocalMaps(); // build ID maps
|
||||||
|
|
||||||
msg(3, 4, std::string("ID bound: ") + std::to_string(bound()));
|
msg(3, 4, std::string("ID bound: ") + std::to_string(bound()));
|
||||||
|
|
||||||
|
if (options & STRIP) stripDebug();
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
strip(); // strip out data we decided to eliminate
|
strip(); // strip out data we decided to eliminate
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
if (options & OPT_LOADSTORE) optLoadStore();
|
if (options & OPT_LOADSTORE) optLoadStore();
|
||||||
if (options & OPT_FWD_LS) forwardLoadStores();
|
if (errorLatch) return;
|
||||||
if (options & DCE_FUNCS) dceFuncs();
|
|
||||||
if (options & DCE_VARS) dceVars();
|
if (options & OPT_FWD_LS) forwardLoadStores();
|
||||||
if (options & DCE_TYPES) dceTypes();
|
if (errorLatch) return;
|
||||||
if (options & MAP_TYPES) mapTypeConst();
|
|
||||||
if (options & MAP_NAMES) mapNames();
|
if (options & DCE_FUNCS) dceFuncs();
|
||||||
if (options & MAP_FUNCS) mapFnBodies();
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
if (options & DCE_VARS) dceVars();
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
if (options & DCE_TYPES) dceTypes();
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
mapRemainder(); // map any unmapped IDs
|
|
||||||
applyMap(); // Now remap each shader to the new IDs we've come up with
|
|
||||||
strip(); // strip out data we decided to eliminate
|
strip(); // strip out data we decided to eliminate
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
stripDeadRefs(); // remove references to things we DCEed
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
// after the last strip, we must clean any debug info referring to now-deleted data
|
||||||
|
|
||||||
|
if (options & MAP_TYPES) mapTypeConst();
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
if (options & MAP_NAMES) mapNames();
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
if (options & MAP_FUNCS) mapFnBodies();
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
if (options & MAP_ALL) {
|
||||||
|
mapRemainder(); // map any unmapped IDs
|
||||||
|
if (errorLatch) return;
|
||||||
|
|
||||||
|
applyMap(); // Now remap each shader to the new IDs we've come up with
|
||||||
|
if (errorLatch) return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remap from a memory image
|
// remap from a memory image
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2015 LunarG, Inc.
|
// Copyright (C) 2015 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef SPIRVREMAPPER_H
|
#ifndef SPIRVREMAPPER_H
|
||||||
|
@ -38,7 +38,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
|
@ -74,7 +75,8 @@ public:
|
||||||
} // namespace SPV
|
} // namespace SPV
|
||||||
|
|
||||||
#if !defined (use_cpp11)
|
#if !defined (use_cpp11)
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
class spirvbin_t : public spirvbin_base_t
|
class spirvbin_t : public spirvbin_base_t
|
||||||
|
@ -82,7 +84,7 @@ class spirvbin_t : public spirvbin_base_t
|
||||||
public:
|
public:
|
||||||
spirvbin_t(int /*verbose = 0*/) { }
|
spirvbin_t(int /*verbose = 0*/) { }
|
||||||
|
|
||||||
void remap(std::vector<unsigned int>& /*spv*/, unsigned int /*opts = 0*/)
|
void remap(std::vector<std::uint32_t>& /*spv*/, unsigned int /*opts = 0*/)
|
||||||
{
|
{
|
||||||
printf("Tool not compiled for C++11, which is required for SPIR-V remapping.\n");
|
printf("Tool not compiled for C++11, which is required for SPIR-V remapping.\n");
|
||||||
exit(5);
|
exit(5);
|
||||||
|
@ -110,7 +112,10 @@ namespace spv {
|
||||||
class spirvbin_t : public spirvbin_base_t
|
class spirvbin_t : public spirvbin_base_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose) { }
|
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose), errorLatch(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual ~spirvbin_t() { }
|
||||||
|
|
||||||
// remap on an existing binary in memory
|
// remap on an existing binary in memory
|
||||||
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||||
|
@ -159,8 +164,11 @@ private:
|
||||||
typedef std::set<int> posmap_t;
|
typedef std::set<int> posmap_t;
|
||||||
typedef std::unordered_map<spv::Id, int> posmap_rev_t;
|
typedef std::unordered_map<spv::Id, int> posmap_rev_t;
|
||||||
|
|
||||||
|
// Maps and ID to the size of its base type, if known.
|
||||||
|
typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;
|
||||||
|
|
||||||
// handle error
|
// handle error
|
||||||
void error(const std::string& txt) const { errorHandler(txt); }
|
void error(const std::string& txt) const { errorLatch = true; errorHandler(txt); }
|
||||||
|
|
||||||
bool isConstOp(spv::Op opCode) const;
|
bool isConstOp(spv::Op opCode) const;
|
||||||
bool isTypeOp(spv::Op opCode) const;
|
bool isTypeOp(spv::Op opCode) const;
|
||||||
|
@ -169,6 +177,8 @@ private:
|
||||||
range_t literalRange(spv::Op opCode) const;
|
range_t literalRange(spv::Op opCode) const;
|
||||||
range_t typeRange(spv::Op opCode) const;
|
range_t typeRange(spv::Op opCode) const;
|
||||||
range_t constRange(spv::Op opCode) const;
|
range_t constRange(spv::Op opCode) const;
|
||||||
|
unsigned typeSizeInWords(spv::Id id) const;
|
||||||
|
unsigned idTypeSizeInWords(spv::Id id) const;
|
||||||
|
|
||||||
spv::Id& asId(unsigned word) { return spv[word]; }
|
spv::Id& asId(unsigned word) { return spv[word]; }
|
||||||
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
||||||
|
@ -177,7 +187,7 @@ private:
|
||||||
spv::Decoration asDecoration(unsigned word) const { return spv::Decoration(spv[word]); }
|
spv::Decoration asDecoration(unsigned word) const { return spv::Decoration(spv[word]); }
|
||||||
unsigned asWordCount(unsigned word) const { return opWordCount(spv[word]); }
|
unsigned asWordCount(unsigned word) const { return opWordCount(spv[word]); }
|
||||||
spv::Id asTypeConstId(unsigned word) const { return asId(word + (isTypeOp(asOpCode(word)) ? 1 : 2)); }
|
spv::Id asTypeConstId(unsigned word) const { return asId(word + (isTypeOp(asOpCode(word)) ? 1 : 2)); }
|
||||||
unsigned typePos(spv::Id id) const;
|
unsigned idPos(spv::Id id) const;
|
||||||
|
|
||||||
static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
|
static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
|
||||||
static spv::Op opOpCode(spirword_t data) { return spv::Op(data & spv::OpCodeMask); }
|
static spv::Op opOpCode(spirword_t data) { return spv::Op(data & spv::OpCodeMask); }
|
||||||
|
@ -233,7 +243,8 @@ private:
|
||||||
|
|
||||||
void applyMap(); // remap per local name map
|
void applyMap(); // remap per local name map
|
||||||
void mapRemainder(); // map any IDs we haven't touched yet
|
void mapRemainder(); // map any IDs we haven't touched yet
|
||||||
void stripDebug(); // strip debug info
|
void stripDebug(); // strip all debug info
|
||||||
|
void stripDeadRefs(); // strips debug info for now-dead references after DCE
|
||||||
void strip(); // remove debug symbols
|
void strip(); // remove debug symbols
|
||||||
|
|
||||||
std::vector<spirword_t> spv; // SPIR words
|
std::vector<spirword_t> spv; // SPIR words
|
||||||
|
@ -258,13 +269,13 @@ private:
|
||||||
// Function start and end. use unordered_map because we'll have
|
// Function start and end. use unordered_map because we'll have
|
||||||
// many fewer functions than IDs.
|
// many fewer functions than IDs.
|
||||||
std::unordered_map<spv::Id, range_t> fnPos;
|
std::unordered_map<spv::Id, range_t> fnPos;
|
||||||
std::unordered_map<spv::Id, range_t> fnPosDCE; // deleted functions
|
|
||||||
|
|
||||||
// Which functions are called, anywhere in the module, with a call count
|
// Which functions are called, anywhere in the module, with a call count
|
||||||
std::unordered_map<spv::Id, int> fnCalls;
|
std::unordered_map<spv::Id, int> fnCalls;
|
||||||
|
|
||||||
posmap_t typeConstPos; // word positions that define types & consts (ordered)
|
posmap_t typeConstPos; // word positions that define types & consts (ordered)
|
||||||
posmap_rev_t typeConstPosR; // reverse map from IDs to positions
|
posmap_rev_t idPosR; // reverse map from IDs to positions
|
||||||
|
typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known.
|
||||||
|
|
||||||
std::vector<spv::Id> idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs
|
std::vector<spv::Id> idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs
|
||||||
|
|
||||||
|
@ -278,6 +289,11 @@ private:
|
||||||
std::uint32_t options;
|
std::uint32_t options;
|
||||||
int verbose; // verbosity level
|
int verbose; // verbosity level
|
||||||
|
|
||||||
|
// Error latch: this is set if the error handler is ever executed. It would be better to
|
||||||
|
// use a try/catch block and throw, but that's not desired for certain environments, so
|
||||||
|
// this is the alternative.
|
||||||
|
mutable bool errorLatch;
|
||||||
|
|
||||||
static errorfn_t errorHandler;
|
static errorfn_t errorHandler;
|
||||||
static logfn_t logHandler;
|
static logfn_t logHandler;
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
//Copyright (C) 2015-2016 Google, Inc.
|
// Copyright (C) 2015-2016 Google, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +21,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
//
|
//
|
||||||
// "Builder" is an interface to fully build SPIR-V IR. Allocate one of
|
// "Builder" is an interface to fully build SPIR-V IR. Allocate one of
|
||||||
|
@ -55,22 +56,36 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
class Builder {
|
class Builder {
|
||||||
public:
|
public:
|
||||||
Builder(unsigned int userNumber, SpvBuildLogger* logger);
|
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
||||||
virtual ~Builder();
|
virtual ~Builder();
|
||||||
|
|
||||||
static const int maxMatrixSize = 4;
|
static const int maxMatrixSize = 4;
|
||||||
|
|
||||||
|
unsigned int getSpvVersion() const { return spvVersion; }
|
||||||
|
|
||||||
void setSource(spv::SourceLanguage lang, int version)
|
void setSource(spv::SourceLanguage lang, int version)
|
||||||
{
|
{
|
||||||
source = lang;
|
source = lang;
|
||||||
sourceVersion = version;
|
sourceVersion = version;
|
||||||
}
|
}
|
||||||
void addSourceExtension(const char* ext) { extensions.push_back(ext); }
|
void setSourceFile(const std::string& file)
|
||||||
|
{
|
||||||
|
Instruction* fileString = new Instruction(getUniqueId(), NoType, OpString);
|
||||||
|
fileString->addStringOperand(file.c_str());
|
||||||
|
sourceFileStringId = fileString->getResultId();
|
||||||
|
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
||||||
|
}
|
||||||
|
void setSourceText(const std::string& text) { sourceText = text; }
|
||||||
|
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
|
||||||
|
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
|
||||||
|
void setEmitOpLines() { emitOpLines = true; }
|
||||||
|
void addExtension(const char* ext) { extensions.insert(ext); }
|
||||||
Id import(const char*);
|
Id import(const char*);
|
||||||
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
||||||
{
|
{
|
||||||
|
@ -91,6 +106,12 @@ public:
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log the current line, and if different than the last one,
|
||||||
|
// issue a new OpLine, using the current file name.
|
||||||
|
void setLine(int line);
|
||||||
|
// Low-level OpLine. See setLine() for a layered helper.
|
||||||
|
void addLine(Id fileName, int line, int column);
|
||||||
|
|
||||||
// For creating new types (will return old type if the requested one was already made).
|
// For creating new types (will return old type if the requested one was already made).
|
||||||
Id makeVoidType();
|
Id makeVoidType();
|
||||||
Id makeBoolType();
|
Id makeBoolType();
|
||||||
|
@ -132,7 +153,10 @@ public:
|
||||||
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
||||||
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
|
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
|
||||||
|
|
||||||
bool isBoolType(Id typeId) const { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
|
bool isBoolType(Id typeId) { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
|
||||||
|
bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
|
||||||
|
bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
|
||||||
|
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
|
||||||
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
|
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
|
||||||
bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
|
bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
|
||||||
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
|
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
|
||||||
|
@ -152,6 +176,13 @@ public:
|
||||||
unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
|
unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
|
||||||
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
|
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
int getScalarTypeWidth(Id typeId) const
|
||||||
|
{
|
||||||
|
Id scalarTypeId = getScalarTypeId(typeId);
|
||||||
|
assert(getTypeClass(scalarTypeId) == OpTypeInt || getTypeClass(scalarTypeId) == OpTypeFloat);
|
||||||
|
return module.getInstruction(scalarTypeId)->getImmediateOperand(0);
|
||||||
|
}
|
||||||
|
|
||||||
int getTypeNumColumns(Id typeId) const
|
int getTypeNumColumns(Id typeId) const
|
||||||
{
|
{
|
||||||
assert(isMatrixType(typeId));
|
assert(isMatrixType(typeId));
|
||||||
|
@ -184,24 +215,32 @@ public:
|
||||||
|
|
||||||
// For making new constants (will return old constant if the requested one was already made).
|
// For making new constants (will return old constant if the requested one was already made).
|
||||||
Id makeBoolConstant(bool b, bool specConstant = false);
|
Id makeBoolConstant(bool b, bool specConstant = false);
|
||||||
|
Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
|
||||||
|
Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); }
|
||||||
|
Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
|
||||||
|
Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); }
|
||||||
Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
|
Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
|
||||||
Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
|
Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
|
||||||
Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
|
Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
|
||||||
Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
|
Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
|
||||||
Id makeFloatConstant(float f, bool specConstant = false);
|
Id makeFloatConstant(float f, bool specConstant = false);
|
||||||
Id makeDoubleConstant(double d, bool specConstant = false);
|
Id makeDoubleConstant(double d, bool specConstant = false);
|
||||||
|
Id makeFloat16Constant(float f16, bool specConstant = false);
|
||||||
|
Id makeFpConstant(Id type, double d, bool specConstant = false);
|
||||||
|
|
||||||
// Turn the array of constants into a proper spv constant of the requested type.
|
// Turn the array of constants into a proper spv constant of the requested type.
|
||||||
Id makeCompositeConstant(Id type, std::vector<Id>& comps, bool specConst = false);
|
Id makeCompositeConstant(Id type, const std::vector<Id>& comps, bool specConst = false);
|
||||||
|
|
||||||
// Methods for adding information outside the CFG.
|
// Methods for adding information outside the CFG.
|
||||||
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
|
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
|
||||||
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
||||||
void addName(Id, const char* name);
|
void addName(Id, const char* name);
|
||||||
void addMemberName(Id, int member, const char* name);
|
void addMemberName(Id, int member, const char* name);
|
||||||
void addLine(Id target, Id fileName, int line, int column);
|
|
||||||
void addDecoration(Id, Decoration, int num = -1);
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
|
void addDecoration(Id, Decoration, const char*);
|
||||||
|
void addDecorationId(Id id, Decoration, Id idDecoration);
|
||||||
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
|
||||||
|
|
||||||
// At the end of what block do the next create*() instructions go?
|
// At the end of what block do the next create*() instructions go?
|
||||||
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
||||||
|
@ -209,13 +248,13 @@ public:
|
||||||
|
|
||||||
// Make the entry-point function. The returned pointer is only valid
|
// Make the entry-point function. The returned pointer is only valid
|
||||||
// for the lifetime of this builder.
|
// for the lifetime of this builder.
|
||||||
Function* makeEntrypoint(const char*);
|
Function* makeEntryPoint(const char*);
|
||||||
|
|
||||||
// Make a shader-style function, and create its entry block if entry is non-zero.
|
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||||
// Return the function, pass back the entry.
|
// Return the function, pass back the entry.
|
||||||
// The returned pointer is only valid for the lifetime of this builder.
|
// The returned pointer is only valid for the lifetime of this builder.
|
||||||
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
|
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
|
||||||
const std::vector<Decoration>& precisions, Block **entry = 0);
|
const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
|
||||||
|
|
||||||
// Create a return. An 'implicit' return is one not appearing in the source
|
// Create a return. An 'implicit' return is one not appearing in the source
|
||||||
// code. In the case of an implicit return, no post-return block is inserted.
|
// code. In the case of an implicit return, no post-return block is inserted.
|
||||||
|
@ -240,16 +279,16 @@ public:
|
||||||
Id createLoad(Id lValue);
|
Id createLoad(Id lValue);
|
||||||
|
|
||||||
// Create an OpAccessChain instruction
|
// Create an OpAccessChain instruction
|
||||||
Id createAccessChain(StorageClass, Id base, std::vector<Id>& offsets);
|
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
||||||
|
|
||||||
// Create an OpArrayLength instruction
|
// Create an OpArrayLength instruction
|
||||||
Id createArrayLength(Id base, unsigned int member);
|
Id createArrayLength(Id base, unsigned int member);
|
||||||
|
|
||||||
// Create an OpCompositeExtract instruction
|
// Create an OpCompositeExtract instruction
|
||||||
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
|
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
|
||||||
Id createCompositeExtract(Id composite, Id typeId, std::vector<unsigned>& indexes);
|
Id createCompositeExtract(Id composite, Id typeId, const std::vector<unsigned>& indexes);
|
||||||
Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
|
Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
|
||||||
Id createCompositeInsert(Id object, Id composite, Id typeId, std::vector<unsigned>& indexes);
|
Id createCompositeInsert(Id object, Id composite, Id typeId, const std::vector<unsigned>& indexes);
|
||||||
|
|
||||||
Id createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex);
|
Id createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex);
|
||||||
Id createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex);
|
Id createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex);
|
||||||
|
@ -263,18 +302,18 @@ public:
|
||||||
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
|
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
|
||||||
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
|
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
|
||||||
Id createOp(Op, Id typeId, const std::vector<Id>& operands);
|
Id createOp(Op, Id typeId, const std::vector<Id>& operands);
|
||||||
Id createFunctionCall(spv::Function*, std::vector<spv::Id>&);
|
Id createFunctionCall(spv::Function*, const std::vector<spv::Id>&);
|
||||||
Id createSpecConstantOp(Op, Id typeId, const std::vector<spv::Id>& operands, const std::vector<unsigned>& literals);
|
Id createSpecConstantOp(Op, Id typeId, const std::vector<spv::Id>& operands, const std::vector<unsigned>& literals);
|
||||||
|
|
||||||
// Take an rvalue (source) and a set of channels to extract from it to
|
// Take an rvalue (source) and a set of channels to extract from it to
|
||||||
// make a new rvalue, which is returned.
|
// make a new rvalue, which is returned.
|
||||||
Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, std::vector<unsigned>& channels);
|
Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, const std::vector<unsigned>& channels);
|
||||||
|
|
||||||
// Take a copy of an lvalue (target) and a source of components, and set the
|
// Take a copy of an lvalue (target) and a source of components, and set the
|
||||||
// source components into the lvalue where the 'channels' say to put them.
|
// source components into the lvalue where the 'channels' say to put them.
|
||||||
// An updated version of the target is returned.
|
// An updated version of the target is returned.
|
||||||
// (No true lvalue or stores are used.)
|
// (No true lvalue or stores are used.)
|
||||||
Id createLvalueSwizzle(Id typeId, Id target, Id source, std::vector<unsigned>& channels);
|
Id createLvalueSwizzle(Id typeId, Id target, Id source, const std::vector<unsigned>& channels);
|
||||||
|
|
||||||
// If both the id and precision are valid, the id
|
// If both the id and precision are valid, the id
|
||||||
// gets tagged with the requested precision.
|
// gets tagged with the requested precision.
|
||||||
|
@ -307,7 +346,7 @@ public:
|
||||||
Id smearScalar(Decoration precision, Id scalarVal, Id vectorType);
|
Id smearScalar(Decoration precision, Id scalarVal, Id vectorType);
|
||||||
|
|
||||||
// Create a call to a built-in function.
|
// Create a call to a built-in function.
|
||||||
Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::vector<Id>& args);
|
Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, const std::vector<Id>& args);
|
||||||
|
|
||||||
// List of parameters used to create a texture operation
|
// List of parameters used to create a texture operation
|
||||||
struct TextureParameters {
|
struct TextureParameters {
|
||||||
|
@ -331,7 +370,7 @@ public:
|
||||||
|
|
||||||
// Emit the OpTextureQuery* instruction that was passed in.
|
// Emit the OpTextureQuery* instruction that was passed in.
|
||||||
// Figure out the right return value and type, and return it.
|
// Figure out the right return value and type, and return it.
|
||||||
Id createTextureQueryCall(Op, const TextureParameters&);
|
Id createTextureQueryCall(Op, const TextureParameters&, bool isUnsignedResult);
|
||||||
|
|
||||||
Id createSamplePositionCall(Decoration precision, Id, Id);
|
Id createSamplePositionCall(Decoration precision, Id, Id);
|
||||||
|
|
||||||
|
@ -342,7 +381,7 @@ public:
|
||||||
Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);
|
Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);
|
||||||
|
|
||||||
// OpCompositeConstruct
|
// OpCompositeConstruct
|
||||||
Id createCompositeConstruct(Id typeId, std::vector<Id>& constituents);
|
Id createCompositeConstruct(Id typeId, const std::vector<Id>& constituents);
|
||||||
|
|
||||||
// vector or scalar constructor
|
// vector or scalar constructor
|
||||||
Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId);
|
Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId);
|
||||||
|
@ -353,7 +392,7 @@ public:
|
||||||
// Helper to use for building nested control flow with if-then-else.
|
// Helper to use for building nested control flow with if-then-else.
|
||||||
class If {
|
class If {
|
||||||
public:
|
public:
|
||||||
If(Id condition, Builder& builder);
|
If(Id condition, unsigned int ctrl, Builder& builder);
|
||||||
~If() {}
|
~If() {}
|
||||||
|
|
||||||
void makeBeginElse();
|
void makeBeginElse();
|
||||||
|
@ -365,6 +404,7 @@ public:
|
||||||
|
|
||||||
Builder& builder;
|
Builder& builder;
|
||||||
Id condition;
|
Id condition;
|
||||||
|
unsigned int control;
|
||||||
Function* function;
|
Function* function;
|
||||||
Block* headerBlock;
|
Block* headerBlock;
|
||||||
Block* thenBlock;
|
Block* thenBlock;
|
||||||
|
@ -384,8 +424,8 @@ public:
|
||||||
// Returns the right set of basic blocks to start each code segment with, so that the caller's
|
// Returns the right set of basic blocks to start each code segment with, so that the caller's
|
||||||
// recursion stack can hold the memory for it.
|
// recursion stack can hold the memory for it.
|
||||||
//
|
//
|
||||||
void makeSwitch(Id condition, int numSegments, std::vector<int>& caseValues, std::vector<int>& valueToSegment, int defaultSegment,
|
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
||||||
std::vector<Block*>& segmentBB); // return argument
|
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
|
||||||
|
|
||||||
// Add a branch to the innermost switch's merge block.
|
// Add a branch to the innermost switch's merge block.
|
||||||
void addSwitchBreak();
|
void addSwitchBreak();
|
||||||
|
@ -466,7 +506,7 @@ public:
|
||||||
|
|
||||||
//
|
//
|
||||||
// the SPIR-V builder maintains a single active chain that
|
// the SPIR-V builder maintains a single active chain that
|
||||||
// the following methods operated on
|
// the following methods operate on
|
||||||
//
|
//
|
||||||
|
|
||||||
// for external save and restore
|
// for external save and restore
|
||||||
|
@ -499,19 +539,22 @@ public:
|
||||||
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
|
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
|
||||||
|
|
||||||
// push a variable component selection onto the access chain; supporting only one, so unsided
|
// push a dynamic component selection onto the access chain, only applicable with a
|
||||||
|
// non-trivial swizzle or no swizzle
|
||||||
void accessChainPushComponent(Id component, Id preSwizzleBaseType)
|
void accessChainPushComponent(Id component, Id preSwizzleBaseType)
|
||||||
{
|
{
|
||||||
|
if (accessChain.swizzle.size() != 1) {
|
||||||
accessChain.component = component;
|
accessChain.component = component;
|
||||||
if (accessChain.preSwizzleBaseType == NoType)
|
if (accessChain.preSwizzleBaseType == NoType)
|
||||||
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// use accessChain and swizzle to store value
|
// use accessChain and swizzle to store value
|
||||||
void accessChainStore(Id rvalue);
|
void accessChainStore(Id rvalue);
|
||||||
|
|
||||||
// use accessChain and swizzle to load an r-value
|
// use accessChain and swizzle to load an r-value
|
||||||
Id accessChainLoad(Decoration precision, Id ResultType);
|
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType);
|
||||||
|
|
||||||
// get the direct pointer for an l-value
|
// get the direct pointer for an l-value
|
||||||
Id accessChainGetLValue();
|
Id accessChainGetLValue();
|
||||||
|
@ -527,7 +570,7 @@ public:
|
||||||
|
|
||||||
void createBranch(Block* block);
|
void createBranch(Block* block);
|
||||||
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
||||||
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
|
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, unsigned int dependencyLength);
|
||||||
|
|
||||||
// Sets to generate opcode for specialization constants.
|
// Sets to generate opcode for specialization constants.
|
||||||
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
||||||
|
@ -539,19 +582,30 @@ public:
|
||||||
protected:
|
protected:
|
||||||
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
|
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
|
||||||
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
|
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
|
||||||
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const;
|
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value);
|
||||||
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
|
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
|
||||||
Id findCompositeConstant(Op typeClass, std::vector<Id>& comps) const;
|
Id findCompositeConstant(Op typeClass, const std::vector<Id>& comps);
|
||||||
|
Id findStructConstant(Id typeId, const std::vector<Id>& comps);
|
||||||
Id collapseAccessChain();
|
Id collapseAccessChain();
|
||||||
|
void remapDynamicSwizzle();
|
||||||
void transferAccessChainSwizzle(bool dynamic);
|
void transferAccessChainSwizzle(bool dynamic);
|
||||||
void simplifyAccessChainSwizzle();
|
void simplifyAccessChainSwizzle();
|
||||||
void createAndSetNoPredecessorBlock(const char*);
|
void createAndSetNoPredecessorBlock(const char*);
|
||||||
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
||||||
|
void dumpSourceInstructions(std::vector<unsigned int>&) const;
|
||||||
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
|
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
||||||
|
|
||||||
|
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||||
SourceLanguage source;
|
SourceLanguage source;
|
||||||
int sourceVersion;
|
int sourceVersion;
|
||||||
std::vector<const char*> extensions;
|
spv::Id sourceFileStringId;
|
||||||
|
std::string sourceText;
|
||||||
|
int currentLine;
|
||||||
|
bool emitOpLines;
|
||||||
|
std::set<std::string> extensions;
|
||||||
|
std::vector<const char*> sourceExtensions;
|
||||||
|
std::vector<const char*> moduleProcesses;
|
||||||
AddressingModel addressModel;
|
AddressingModel addressModel;
|
||||||
MemoryModel memoryModel;
|
MemoryModel memoryModel;
|
||||||
std::set<spv::Capability> capabilities;
|
std::set<spv::Capability> capabilities;
|
||||||
|
@ -559,24 +613,25 @@ public:
|
||||||
Module module;
|
Module module;
|
||||||
Block* buildPoint;
|
Block* buildPoint;
|
||||||
Id uniqueId;
|
Id uniqueId;
|
||||||
Function* mainFunction;
|
Function* entryPointFunction;
|
||||||
bool generatingOpCodeForSpecConst;
|
bool generatingOpCodeForSpecConst;
|
||||||
AccessChain accessChain;
|
AccessChain accessChain;
|
||||||
|
|
||||||
// special blocks of instructions for output
|
// special blocks of instructions for output
|
||||||
|
std::vector<std::unique_ptr<Instruction> > strings;
|
||||||
std::vector<std::unique_ptr<Instruction> > imports;
|
std::vector<std::unique_ptr<Instruction> > imports;
|
||||||
std::vector<std::unique_ptr<Instruction> > entryPoints;
|
std::vector<std::unique_ptr<Instruction> > entryPoints;
|
||||||
std::vector<std::unique_ptr<Instruction> > executionModes;
|
std::vector<std::unique_ptr<Instruction> > executionModes;
|
||||||
std::vector<std::unique_ptr<Instruction> > names;
|
std::vector<std::unique_ptr<Instruction> > names;
|
||||||
std::vector<std::unique_ptr<Instruction> > lines;
|
|
||||||
std::vector<std::unique_ptr<Instruction> > decorations;
|
std::vector<std::unique_ptr<Instruction> > decorations;
|
||||||
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
|
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
|
||||||
std::vector<std::unique_ptr<Instruction> > externals;
|
std::vector<std::unique_ptr<Instruction> > externals;
|
||||||
std::vector<std::unique_ptr<Function> > functions;
|
std::vector<std::unique_ptr<Function> > functions;
|
||||||
|
|
||||||
// not output, internally used for quick & dirty canonical (unique) creation
|
// not output, internally used for quick & dirty canonical (unique) creation
|
||||||
std::vector<Instruction*> groupedConstants[OpConstant]; // all types appear before OpConstant
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants; // map type opcodes to constant inst.
|
||||||
std::vector<Instruction*> groupedTypes[OpConstant];
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; // map struct-id to constant instructions
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes; // map type opcodes to type instructions
|
||||||
|
|
||||||
// stack of switches
|
// stack of switches
|
||||||
std::stack<Block*> switchMerges;
|
std::stack<Block*> switchMerges;
|
||||||
|
@ -584,7 +639,7 @@ public:
|
||||||
// Our loop stack.
|
// Our loop stack.
|
||||||
std::stack<LoopBlocks> loops;
|
std::stack<LoopBlocks> loops;
|
||||||
|
|
||||||
// The stream for outputing warnings and errors.
|
// The stream for outputting warnings and errors.
|
||||||
SpvBuildLogger* logger;
|
SpvBuildLogger* logger;
|
||||||
}; // end Builder class
|
}; // end Builder class
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright (c) 2015-2016 The Khronos Group 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.
|
||||||
|
|
||||||
|
#ifndef LIBSPIRV_UTIL_BITUTILS_H_
|
||||||
|
#define LIBSPIRV_UTIL_BITUTILS_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace spvutils {
|
||||||
|
|
||||||
|
// Performs a bitwise copy of source to the destination type Dest.
|
||||||
|
template <typename Dest, typename Src>
|
||||||
|
Dest BitwiseCast(Src source) {
|
||||||
|
Dest dest;
|
||||||
|
static_assert(sizeof(source) == sizeof(dest),
|
||||||
|
"BitwiseCast: Source and destination must have the same size");
|
||||||
|
std::memcpy(&dest, &source, sizeof(dest));
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBits<T, First, Num> returns an integer of type <T> with bits set
|
||||||
|
// for position <First> through <First + Num - 1>, counting from the least
|
||||||
|
// significant bit. In particular when Num == 0, no positions are set to 1.
|
||||||
|
// A static assert will be triggered if First + Num > sizeof(T) * 8, that is,
|
||||||
|
// a bit that will not fit in the underlying type is set.
|
||||||
|
template <typename T, size_t First = 0, size_t Num = 0>
|
||||||
|
struct SetBits {
|
||||||
|
static_assert(First < sizeof(T) * 8,
|
||||||
|
"Tried to set a bit that is shifted too far.");
|
||||||
|
const static T get = (T(1) << First) | SetBits<T, First + 1, Num - 1>::get;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t Last>
|
||||||
|
struct SetBits<T, Last, 0> {
|
||||||
|
const static T get = T(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is all compile-time so we can put our tests right here.
|
||||||
|
static_assert(SetBits<uint32_t, 0, 0>::get == uint32_t(0x00000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 1>::get == uint32_t(0x00000001),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 31, 1>::get == uint32_t(0x80000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 1, 2>::get == uint32_t(0x00000006),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 30, 2>::get == uint32_t(0xc0000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 31>::get == uint32_t(0x7FFFFFFF),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 32>::get == uint32_t(0xFFFFFFFF),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 16, 16>::get == uint32_t(0xFFFF0000),
|
||||||
|
"SetBits failed");
|
||||||
|
|
||||||
|
static_assert(SetBits<uint64_t, 0, 1>::get == uint64_t(0x0000000000000001LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 63, 1>::get == uint64_t(0x8000000000000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 62, 2>::get == uint64_t(0xc000000000000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 31, 1>::get == uint64_t(0x0000000080000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 16, 16>::get == uint64_t(0x00000000FFFF0000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
|
||||||
|
} // namespace spvutils
|
||||||
|
|
||||||
|
#endif // LIBSPIRV_UTIL_BITUTILS_H_
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,41 +19,58 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disassembler for SPIR-V.
|
// Disassembler for SPIR-V.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace spv {
|
|
||||||
// Include C-based headers that don't have a namespace
|
|
||||||
#include "GLSL.std.450.h"
|
|
||||||
}
|
|
||||||
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
|
||||||
|
|
||||||
#include "disassemble.h"
|
#include "disassemble.h"
|
||||||
#include "doc.h"
|
#include "doc.h"
|
||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
extern "C" {
|
||||||
|
// Include C-based headers that don't have a namespace
|
||||||
|
#include "GLSL.std.450.h"
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
#include "GLSL.ext.AMD.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
#include "GLSL.ext.NV.h"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void Kill(std::ostream& out, const char* message)
|
static void Kill(std::ostream& out, const char* message)
|
||||||
{
|
{
|
||||||
|
@ -64,6 +81,15 @@ static void Kill(std::ostream& out, const char* message)
|
||||||
// used to identify the extended instruction library imported when printing
|
// used to identify the extended instruction library imported when printing
|
||||||
enum ExtInstSet {
|
enum ExtInstSet {
|
||||||
GLSL450Inst,
|
GLSL450Inst,
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
GLSLextAMDInst,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
GLSLextNVInst,
|
||||||
|
#endif
|
||||||
|
|
||||||
OpenCLExtInst,
|
OpenCLExtInst,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -205,10 +231,12 @@ void SpirvStream::outputIndent()
|
||||||
|
|
||||||
void SpirvStream::formatId(Id id, std::stringstream& idStream)
|
void SpirvStream::formatId(Id id, std::stringstream& idStream)
|
||||||
{
|
{
|
||||||
|
if (id != 0) {
|
||||||
|
// On instructions with no IDs, this is called with "0", which does not
|
||||||
|
// have to be within ID bounds on null shaders.
|
||||||
if (id >= bound)
|
if (id >= bound)
|
||||||
Kill(out, "Bad <id>");
|
Kill(out, "Bad <id>");
|
||||||
|
|
||||||
if (id != 0) {
|
|
||||||
idStream << id;
|
idStream << id;
|
||||||
if (idDescriptor[id].size() > 0)
|
if (idDescriptor[id].size() > 0)
|
||||||
idStream << "(" << idDescriptor[id] << ")";
|
idStream << "(" << idDescriptor[id] << ")";
|
||||||
|
@ -322,13 +350,24 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
idDescriptor[resultId] = (const char*)(&stream[word]);
|
idDescriptor[resultId] = (const char*)(&stream[word]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (idDescriptor[resultId].size() == 0) {
|
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
|
||||||
switch (opCode) {
|
switch (opCode) {
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
idDescriptor[resultId] = "int";
|
switch (stream[word]) {
|
||||||
|
case 8: idDescriptor[resultId] = "int8_t"; break;
|
||||||
|
case 16: idDescriptor[resultId] = "int16_t"; break;
|
||||||
|
default: assert(0); // fallthrough
|
||||||
|
case 32: idDescriptor[resultId] = "int"; break;
|
||||||
|
case 64: idDescriptor[resultId] = "int64_t"; break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpTypeFloat:
|
case OpTypeFloat:
|
||||||
idDescriptor[resultId] = "float";
|
switch (stream[word]) {
|
||||||
|
case 16: idDescriptor[resultId] = "float16_t"; break;
|
||||||
|
default: assert(0); // fallthrough
|
||||||
|
case 32: idDescriptor[resultId] = "float"; break;
|
||||||
|
case 64: idDescriptor[resultId] = "float64_t"; break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OpTypeBool:
|
case OpTypeBool:
|
||||||
idDescriptor[resultId] = "bool";
|
idDescriptor[resultId] = "bool";
|
||||||
|
@ -340,8 +379,18 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
idDescriptor[resultId] = "ptr";
|
idDescriptor[resultId] = "ptr";
|
||||||
break;
|
break;
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
if (idDescriptor[stream[word]].size() > 0)
|
if (idDescriptor[stream[word]].size() > 0) {
|
||||||
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
|
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
|
||||||
|
if (strstr(idDescriptor[stream[word]].c_str(), "8")) {
|
||||||
|
idDescriptor[resultId].append("8");
|
||||||
|
}
|
||||||
|
if (strstr(idDescriptor[stream[word]].c_str(), "16")) {
|
||||||
|
idDescriptor[resultId].append("16");
|
||||||
|
}
|
||||||
|
if (strstr(idDescriptor[stream[word]].c_str(), "64")) {
|
||||||
|
idDescriptor[resultId].append("64");
|
||||||
|
}
|
||||||
|
}
|
||||||
idDescriptor[resultId].append("vec");
|
idDescriptor[resultId].append("vec");
|
||||||
switch (stream[word + 1]) {
|
switch (stream[word + 1]) {
|
||||||
case 2: idDescriptor[resultId].append("2"); break;
|
case 2: idDescriptor[resultId].append("2"); break;
|
||||||
|
@ -446,14 +495,38 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
||||||
--numOperands;
|
--numOperands;
|
||||||
if (opCode == OpExtInst) {
|
if (opCode == OpExtInst) {
|
||||||
ExtInstSet extInstSet = GLSL450Inst;
|
ExtInstSet extInstSet = GLSL450Inst;
|
||||||
if (0 == memcmp("OpenCL", (const char*)(idDescriptor[stream[word-2]].c_str()), 6)) {
|
const char* name = idDescriptor[stream[word - 2]].c_str();
|
||||||
|
if (0 == memcmp("OpenCL", name, 6)) {
|
||||||
extInstSet = OpenCLExtInst;
|
extInstSet = OpenCLExtInst;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
|
||||||
|
extInstSet = GLSLextAMDInst;
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
}else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) {
|
||||||
|
extInstSet = GLSLextNVInst;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
unsigned entrypoint = stream[word - 1];
|
unsigned entrypoint = stream[word - 1];
|
||||||
if (extInstSet == GLSL450Inst) {
|
if (extInstSet == GLSL450Inst) {
|
||||||
if (entrypoint < GLSLstd450Count) {
|
if (entrypoint < GLSLstd450Count) {
|
||||||
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
||||||
}
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (extInstSet == GLSLextAMDInst) {
|
||||||
|
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
}
|
||||||
|
else if (extInstSet == GLSLextNVInst) {
|
||||||
|
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -561,6 +634,79 @@ static void GLSLstd450GetDebugNames(const char** names)
|
||||||
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
|
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
|
{
|
||||||
|
if (strcmp(name, spv::E_SPV_AMD_shader_ballot) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case SwizzleInvocationsAMD: return "SwizzleInvocationsAMD";
|
||||||
|
case SwizzleInvocationsMaskedAMD: return "SwizzleInvocationsMaskedAMD";
|
||||||
|
case WriteInvocationAMD: return "WriteInvocationAMD";
|
||||||
|
case MbcntAMD: return "MbcntAMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, spv::E_SPV_AMD_shader_trinary_minmax) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case FMin3AMD: return "FMin3AMD";
|
||||||
|
case UMin3AMD: return "UMin3AMD";
|
||||||
|
case SMin3AMD: return "SMin3AMD";
|
||||||
|
case FMax3AMD: return "FMax3AMD";
|
||||||
|
case UMax3AMD: return "UMax3AMD";
|
||||||
|
case SMax3AMD: return "SMax3AMD";
|
||||||
|
case FMid3AMD: return "FMid3AMD";
|
||||||
|
case UMid3AMD: return "UMid3AMD";
|
||||||
|
case SMid3AMD: return "SMid3AMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, spv::E_SPV_AMD_shader_explicit_vertex_parameter) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case InterpolateAtVertexAMD: return "InterpolateAtVertexAMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(name, spv::E_SPV_AMD_gcn_shader) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case CubeFaceIndexAMD: return "CubeFaceIndexAMD";
|
||||||
|
case CubeFaceCoordAMD: return "CubeFaceCoordAMD";
|
||||||
|
case TimeAMD: return "TimeAMD";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Bad";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
|
{
|
||||||
|
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 ||
|
||||||
|
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||||
|
case DecorationPassthroughNV: return "PassthroughNV";
|
||||||
|
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||||
|
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||||
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
|
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||||
|
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
||||||
|
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
|
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
|
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
||||||
|
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||||
|
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "Bad";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
||||||
{
|
{
|
||||||
SpirvStream SpirvStream(out, stream);
|
SpirvStream SpirvStream(out, stream);
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Disassembler for SPIR-V.
|
// Disassembler for SPIR-V.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2014-2015 LunarG, Inc.
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,23 +19,25 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parameterize the SPIR-V enumerants.
|
// Parameterize the SPIR-V enumerants.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "spirv.hpp"
|
#include "spirv.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -188,7 +190,6 @@ protected:
|
||||||
class EnumParameters {
|
class EnumParameters {
|
||||||
public:
|
public:
|
||||||
EnumParameters() : desc(0) { }
|
EnumParameters() : desc(0) { }
|
||||||
EnumCaps caps;
|
|
||||||
const char* desc;
|
const char* desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -233,7 +234,6 @@ public:
|
||||||
bool hasType() const { return typePresent != 0; }
|
bool hasType() const { return typePresent != 0; }
|
||||||
|
|
||||||
const char* opDesc;
|
const char* opDesc;
|
||||||
EnumCaps capabilities;
|
|
||||||
OpcodeClass opClass;
|
OpcodeClass opClass;
|
||||||
OperandParameters operands;
|
OperandParameters operands;
|
||||||
|
|
||||||
|
@ -242,8 +242,6 @@ protected:
|
||||||
int resultPresent : 1;
|
int resultPresent : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
const int OpcodeCeiling = 321;
|
|
||||||
|
|
||||||
// The set of objects that hold all the instruction/operand
|
// The set of objects that hold all the instruction/operand
|
||||||
// parameterization information.
|
// parameterization information.
|
||||||
extern InstructionParameters InstructionDesc[];
|
extern InstructionParameters InstructionDesc[];
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014-2016 The Khronos Group Inc.
|
// Copyright (c) 2014-2018 The Khronos Group Inc.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and/or associated documentation files (the "Materials"),
|
// of this software and/or associated documentation files (the "Materials"),
|
||||||
|
@ -46,12 +46,12 @@ namespace spv {
|
||||||
|
|
||||||
typedef unsigned int Id;
|
typedef unsigned int Id;
|
||||||
|
|
||||||
#define SPV_VERSION 0x10000
|
#define SPV_VERSION 0x10300
|
||||||
#define SPV_REVISION 6
|
#define SPV_REVISION 1
|
||||||
|
|
||||||
static const unsigned int MagicNumber = 0x07230203;
|
static const unsigned int MagicNumber = 0x07230203;
|
||||||
static const unsigned int Version = 0x00010000;
|
static const unsigned int Version = 0x00010300;
|
||||||
static const unsigned int Revision = 6;
|
static const unsigned int Revision = 1;
|
||||||
static const unsigned int OpCodeMask = 0xffff;
|
static const unsigned int OpCodeMask = 0xffff;
|
||||||
static const unsigned int WordCountShift = 16;
|
static const unsigned int WordCountShift = 16;
|
||||||
|
|
||||||
|
@ -122,6 +122,15 @@ enum ExecutionMode {
|
||||||
ExecutionModeOutputTriangleStrip = 29,
|
ExecutionModeOutputTriangleStrip = 29,
|
||||||
ExecutionModeVecTypeHint = 30,
|
ExecutionModeVecTypeHint = 30,
|
||||||
ExecutionModeContractionOff = 31,
|
ExecutionModeContractionOff = 31,
|
||||||
|
ExecutionModeInitializer = 33,
|
||||||
|
ExecutionModeFinalizer = 34,
|
||||||
|
ExecutionModeSubgroupSize = 35,
|
||||||
|
ExecutionModeSubgroupsPerWorkgroup = 36,
|
||||||
|
ExecutionModeSubgroupsPerWorkgroupId = 37,
|
||||||
|
ExecutionModeLocalSizeId = 38,
|
||||||
|
ExecutionModeLocalSizeHintId = 39,
|
||||||
|
ExecutionModePostDepthCoverage = 4446,
|
||||||
|
ExecutionModeStencilRefReplacingEXT = 5027,
|
||||||
ExecutionModeMax = 0x7fffffff,
|
ExecutionModeMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -138,6 +147,7 @@ enum StorageClass {
|
||||||
StorageClassPushConstant = 9,
|
StorageClassPushConstant = 9,
|
||||||
StorageClassAtomicCounter = 10,
|
StorageClassAtomicCounter = 10,
|
||||||
StorageClassImage = 11,
|
StorageClassImage = 11,
|
||||||
|
StorageClassStorageBuffer = 12,
|
||||||
StorageClassMax = 0x7fffffff,
|
StorageClassMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -375,6 +385,17 @@ enum Decoration {
|
||||||
DecorationNoContraction = 42,
|
DecorationNoContraction = 42,
|
||||||
DecorationInputAttachmentIndex = 43,
|
DecorationInputAttachmentIndex = 43,
|
||||||
DecorationAlignment = 44,
|
DecorationAlignment = 44,
|
||||||
|
DecorationMaxByteOffset = 45,
|
||||||
|
DecorationAlignmentId = 46,
|
||||||
|
DecorationMaxByteOffsetId = 47,
|
||||||
|
DecorationExplicitInterpAMD = 4999,
|
||||||
|
DecorationOverrideCoverageNV = 5248,
|
||||||
|
DecorationPassthroughNV = 5250,
|
||||||
|
DecorationViewportRelativeNV = 5252,
|
||||||
|
DecorationSecondaryViewportRelativeNV = 5256,
|
||||||
|
DecorationNonUniformEXT = 5300,
|
||||||
|
DecorationHlslCounterBufferGOOGLE = 5634,
|
||||||
|
DecorationHlslSemanticGOOGLE = 5635,
|
||||||
DecorationMax = 0x7fffffff,
|
DecorationMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -420,6 +441,35 @@ enum BuiltIn {
|
||||||
BuiltInSubgroupLocalInvocationId = 41,
|
BuiltInSubgroupLocalInvocationId = 41,
|
||||||
BuiltInVertexIndex = 42,
|
BuiltInVertexIndex = 42,
|
||||||
BuiltInInstanceIndex = 43,
|
BuiltInInstanceIndex = 43,
|
||||||
|
BuiltInSubgroupEqMask = 4416,
|
||||||
|
BuiltInSubgroupEqMaskKHR = 4416,
|
||||||
|
BuiltInSubgroupGeMask = 4417,
|
||||||
|
BuiltInSubgroupGeMaskKHR = 4417,
|
||||||
|
BuiltInSubgroupGtMask = 4418,
|
||||||
|
BuiltInSubgroupGtMaskKHR = 4418,
|
||||||
|
BuiltInSubgroupLeMask = 4419,
|
||||||
|
BuiltInSubgroupLeMaskKHR = 4419,
|
||||||
|
BuiltInSubgroupLtMask = 4420,
|
||||||
|
BuiltInSubgroupLtMaskKHR = 4420,
|
||||||
|
BuiltInBaseVertex = 4424,
|
||||||
|
BuiltInBaseInstance = 4425,
|
||||||
|
BuiltInDrawIndex = 4426,
|
||||||
|
BuiltInDeviceIndex = 4438,
|
||||||
|
BuiltInViewIndex = 4440,
|
||||||
|
BuiltInBaryCoordNoPerspAMD = 4992,
|
||||||
|
BuiltInBaryCoordNoPerspCentroidAMD = 4993,
|
||||||
|
BuiltInBaryCoordNoPerspSampleAMD = 4994,
|
||||||
|
BuiltInBaryCoordSmoothAMD = 4995,
|
||||||
|
BuiltInBaryCoordSmoothCentroidAMD = 4996,
|
||||||
|
BuiltInBaryCoordSmoothSampleAMD = 4997,
|
||||||
|
BuiltInBaryCoordPullModelAMD = 4998,
|
||||||
|
BuiltInFragStencilRefEXT = 5014,
|
||||||
|
BuiltInViewportMaskNV = 5253,
|
||||||
|
BuiltInSecondaryPositionNV = 5257,
|
||||||
|
BuiltInSecondaryViewportMaskNV = 5258,
|
||||||
|
BuiltInPositionPerViewNV = 5261,
|
||||||
|
BuiltInViewportMaskPerViewNV = 5262,
|
||||||
|
BuiltInFullyCoveredEXT = 5264,
|
||||||
BuiltInMax = 0x7fffffff,
|
BuiltInMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -438,6 +488,8 @@ enum SelectionControlMask {
|
||||||
enum LoopControlShift {
|
enum LoopControlShift {
|
||||||
LoopControlUnrollShift = 0,
|
LoopControlUnrollShift = 0,
|
||||||
LoopControlDontUnrollShift = 1,
|
LoopControlDontUnrollShift = 1,
|
||||||
|
LoopControlDependencyInfiniteShift = 2,
|
||||||
|
LoopControlDependencyLengthShift = 3,
|
||||||
LoopControlMax = 0x7fffffff,
|
LoopControlMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -445,6 +497,8 @@ enum LoopControlMask {
|
||||||
LoopControlMaskNone = 0,
|
LoopControlMaskNone = 0,
|
||||||
LoopControlUnrollMask = 0x00000001,
|
LoopControlUnrollMask = 0x00000001,
|
||||||
LoopControlDontUnrollMask = 0x00000002,
|
LoopControlDontUnrollMask = 0x00000002,
|
||||||
|
LoopControlDependencyInfiniteMask = 0x00000004,
|
||||||
|
LoopControlDependencyLengthMask = 0x00000008,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FunctionControlShift {
|
enum FunctionControlShift {
|
||||||
|
@ -518,6 +572,10 @@ enum GroupOperation {
|
||||||
GroupOperationReduce = 0,
|
GroupOperationReduce = 0,
|
||||||
GroupOperationInclusiveScan = 1,
|
GroupOperationInclusiveScan = 1,
|
||||||
GroupOperationExclusiveScan = 2,
|
GroupOperationExclusiveScan = 2,
|
||||||
|
GroupOperationClusteredReduce = 3,
|
||||||
|
GroupOperationPartitionedReduceNV = 6,
|
||||||
|
GroupOperationPartitionedInclusiveScanNV = 7,
|
||||||
|
GroupOperationPartitionedExclusiveScanNV = 8,
|
||||||
GroupOperationMax = 0x7fffffff,
|
GroupOperationMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -595,6 +653,61 @@ enum Capability {
|
||||||
CapabilityStorageImageReadWithoutFormat = 55,
|
CapabilityStorageImageReadWithoutFormat = 55,
|
||||||
CapabilityStorageImageWriteWithoutFormat = 56,
|
CapabilityStorageImageWriteWithoutFormat = 56,
|
||||||
CapabilityMultiViewport = 57,
|
CapabilityMultiViewport = 57,
|
||||||
|
CapabilitySubgroupDispatch = 58,
|
||||||
|
CapabilityNamedBarrier = 59,
|
||||||
|
CapabilityPipeStorage = 60,
|
||||||
|
CapabilityGroupNonUniform = 61,
|
||||||
|
CapabilityGroupNonUniformVote = 62,
|
||||||
|
CapabilityGroupNonUniformArithmetic = 63,
|
||||||
|
CapabilityGroupNonUniformBallot = 64,
|
||||||
|
CapabilityGroupNonUniformShuffle = 65,
|
||||||
|
CapabilityGroupNonUniformShuffleRelative = 66,
|
||||||
|
CapabilityGroupNonUniformClustered = 67,
|
||||||
|
CapabilityGroupNonUniformQuad = 68,
|
||||||
|
CapabilitySubgroupBallotKHR = 4423,
|
||||||
|
CapabilityDrawParameters = 4427,
|
||||||
|
CapabilitySubgroupVoteKHR = 4431,
|
||||||
|
CapabilityStorageBuffer16BitAccess = 4433,
|
||||||
|
CapabilityStorageUniformBufferBlock16 = 4433,
|
||||||
|
CapabilityStorageUniform16 = 4434,
|
||||||
|
CapabilityUniformAndStorageBuffer16BitAccess = 4434,
|
||||||
|
CapabilityStoragePushConstant16 = 4435,
|
||||||
|
CapabilityStorageInputOutput16 = 4436,
|
||||||
|
CapabilityDeviceGroup = 4437,
|
||||||
|
CapabilityMultiView = 4439,
|
||||||
|
CapabilityVariablePointersStorageBuffer = 4441,
|
||||||
|
CapabilityVariablePointers = 4442,
|
||||||
|
CapabilityAtomicStorageOps = 4445,
|
||||||
|
CapabilitySampleMaskPostDepthCoverage = 4447,
|
||||||
|
CapabilityFloat16ImageAMD = 5008,
|
||||||
|
CapabilityImageGatherBiasLodAMD = 5009,
|
||||||
|
CapabilityFragmentMaskAMD = 5010,
|
||||||
|
CapabilityStencilExportEXT = 5013,
|
||||||
|
CapabilityImageReadWriteLodAMD = 5015,
|
||||||
|
CapabilitySampleMaskOverrideCoverageNV = 5249,
|
||||||
|
CapabilityGeometryShaderPassthroughNV = 5251,
|
||||||
|
CapabilityShaderViewportIndexLayerEXT = 5254,
|
||||||
|
CapabilityShaderViewportIndexLayerNV = 5254,
|
||||||
|
CapabilityShaderViewportMaskNV = 5255,
|
||||||
|
CapabilityShaderStereoViewNV = 5259,
|
||||||
|
CapabilityPerViewAttributesNV = 5260,
|
||||||
|
CapabilityFragmentFullyCoveredEXT = 5265,
|
||||||
|
CapabilityGroupNonUniformPartitionedNV = 5297,
|
||||||
|
CapabilityShaderNonUniformEXT = 5301,
|
||||||
|
CapabilityRuntimeDescriptorArrayEXT = 5302,
|
||||||
|
CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303,
|
||||||
|
CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304,
|
||||||
|
CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305,
|
||||||
|
CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306,
|
||||||
|
CapabilitySampledImageArrayNonUniformIndexingEXT = 5307,
|
||||||
|
CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308,
|
||||||
|
CapabilityStorageImageArrayNonUniformIndexingEXT = 5309,
|
||||||
|
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
|
||||||
|
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
|
||||||
|
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
||||||
|
CapabilitySubgroupShuffleINTEL = 5568,
|
||||||
|
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||||
|
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||||
CapabilityMax = 0x7fffffff,
|
CapabilityMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -893,6 +1006,79 @@ enum Op {
|
||||||
OpAtomicFlagTestAndSet = 318,
|
OpAtomicFlagTestAndSet = 318,
|
||||||
OpAtomicFlagClear = 319,
|
OpAtomicFlagClear = 319,
|
||||||
OpImageSparseRead = 320,
|
OpImageSparseRead = 320,
|
||||||
|
OpSizeOf = 321,
|
||||||
|
OpTypePipeStorage = 322,
|
||||||
|
OpConstantPipeStorage = 323,
|
||||||
|
OpCreatePipeFromPipeStorage = 324,
|
||||||
|
OpGetKernelLocalSizeForSubgroupCount = 325,
|
||||||
|
OpGetKernelMaxNumSubgroups = 326,
|
||||||
|
OpTypeNamedBarrier = 327,
|
||||||
|
OpNamedBarrierInitialize = 328,
|
||||||
|
OpMemoryNamedBarrier = 329,
|
||||||
|
OpModuleProcessed = 330,
|
||||||
|
OpExecutionModeId = 331,
|
||||||
|
OpDecorateId = 332,
|
||||||
|
OpGroupNonUniformElect = 333,
|
||||||
|
OpGroupNonUniformAll = 334,
|
||||||
|
OpGroupNonUniformAny = 335,
|
||||||
|
OpGroupNonUniformAllEqual = 336,
|
||||||
|
OpGroupNonUniformBroadcast = 337,
|
||||||
|
OpGroupNonUniformBroadcastFirst = 338,
|
||||||
|
OpGroupNonUniformBallot = 339,
|
||||||
|
OpGroupNonUniformInverseBallot = 340,
|
||||||
|
OpGroupNonUniformBallotBitExtract = 341,
|
||||||
|
OpGroupNonUniformBallotBitCount = 342,
|
||||||
|
OpGroupNonUniformBallotFindLSB = 343,
|
||||||
|
OpGroupNonUniformBallotFindMSB = 344,
|
||||||
|
OpGroupNonUniformShuffle = 345,
|
||||||
|
OpGroupNonUniformShuffleXor = 346,
|
||||||
|
OpGroupNonUniformShuffleUp = 347,
|
||||||
|
OpGroupNonUniformShuffleDown = 348,
|
||||||
|
OpGroupNonUniformIAdd = 349,
|
||||||
|
OpGroupNonUniformFAdd = 350,
|
||||||
|
OpGroupNonUniformIMul = 351,
|
||||||
|
OpGroupNonUniformFMul = 352,
|
||||||
|
OpGroupNonUniformSMin = 353,
|
||||||
|
OpGroupNonUniformUMin = 354,
|
||||||
|
OpGroupNonUniformFMin = 355,
|
||||||
|
OpGroupNonUniformSMax = 356,
|
||||||
|
OpGroupNonUniformUMax = 357,
|
||||||
|
OpGroupNonUniformFMax = 358,
|
||||||
|
OpGroupNonUniformBitwiseAnd = 359,
|
||||||
|
OpGroupNonUniformBitwiseOr = 360,
|
||||||
|
OpGroupNonUniformBitwiseXor = 361,
|
||||||
|
OpGroupNonUniformLogicalAnd = 362,
|
||||||
|
OpGroupNonUniformLogicalOr = 363,
|
||||||
|
OpGroupNonUniformLogicalXor = 364,
|
||||||
|
OpGroupNonUniformQuadBroadcast = 365,
|
||||||
|
OpGroupNonUniformQuadSwap = 366,
|
||||||
|
OpSubgroupBallotKHR = 4421,
|
||||||
|
OpSubgroupFirstInvocationKHR = 4422,
|
||||||
|
OpSubgroupAllKHR = 4428,
|
||||||
|
OpSubgroupAnyKHR = 4429,
|
||||||
|
OpSubgroupAllEqualKHR = 4430,
|
||||||
|
OpSubgroupReadInvocationKHR = 4432,
|
||||||
|
OpGroupIAddNonUniformAMD = 5000,
|
||||||
|
OpGroupFAddNonUniformAMD = 5001,
|
||||||
|
OpGroupFMinNonUniformAMD = 5002,
|
||||||
|
OpGroupUMinNonUniformAMD = 5003,
|
||||||
|
OpGroupSMinNonUniformAMD = 5004,
|
||||||
|
OpGroupFMaxNonUniformAMD = 5005,
|
||||||
|
OpGroupUMaxNonUniformAMD = 5006,
|
||||||
|
OpGroupSMaxNonUniformAMD = 5007,
|
||||||
|
OpFragmentMaskFetchAMD = 5011,
|
||||||
|
OpFragmentFetchAMD = 5012,
|
||||||
|
OpGroupNonUniformPartitionNV = 5296,
|
||||||
|
OpSubgroupShuffleINTEL = 5571,
|
||||||
|
OpSubgroupShuffleDownINTEL = 5572,
|
||||||
|
OpSubgroupShuffleUpINTEL = 5573,
|
||||||
|
OpSubgroupShuffleXorINTEL = 5574,
|
||||||
|
OpSubgroupBlockReadINTEL = 5575,
|
||||||
|
OpSubgroupBlockWriteINTEL = 5576,
|
||||||
|
OpSubgroupImageBlockReadINTEL = 5577,
|
||||||
|
OpSubgroupImageBlockWriteINTEL = 5578,
|
||||||
|
OpDecorateStringGOOGLE = 5632,
|
||||||
|
OpMemberDecorateStringGOOGLE = 5633,
|
||||||
OpMax = 0x7fffffff,
|
OpMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2014 LunarG, Inc.
|
// Copyright (C) 2014 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// SPIRV-IR
|
// SPIRV-IR
|
||||||
//
|
//
|
||||||
|
@ -65,12 +65,17 @@ const Id NoResult = 0;
|
||||||
const Id NoType = 0;
|
const Id NoType = 0;
|
||||||
|
|
||||||
const Decoration NoPrecision = DecorationMax;
|
const Decoration NoPrecision = DecorationMax;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define POTENTIALLY_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
# define POTENTIALLY_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
POTENTIALLY_UNUSED
|
||||||
const MemorySemanticsMask MemorySemanticsAllMemory =
|
const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||||
(MemorySemanticsMask)(MemorySemanticsSequentiallyConsistentMask |
|
(MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
|
||||||
MemorySemanticsUniformMemoryMask |
|
|
||||||
MemorySemanticsSubgroupMemoryMask |
|
|
||||||
MemorySemanticsWorkgroupMemoryMask |
|
MemorySemanticsWorkgroupMemoryMask |
|
||||||
MemorySemanticsCrossWorkgroupMemoryMask |
|
|
||||||
MemorySemanticsAtomicCounterMemoryMask |
|
MemorySemanticsAtomicCounterMemoryMask |
|
||||||
MemorySemanticsImageMemoryMask);
|
MemorySemanticsImageMemoryMask);
|
||||||
|
|
||||||
|
@ -87,7 +92,6 @@ public:
|
||||||
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
||||||
void addStringOperand(const char* str)
|
void addStringOperand(const char* str)
|
||||||
{
|
{
|
||||||
originalString = str;
|
|
||||||
unsigned int word;
|
unsigned int word;
|
||||||
char* wordString = (char*)&word;
|
char* wordString = (char*)&word;
|
||||||
char* wordPtr = wordString;
|
char* wordPtr = wordString;
|
||||||
|
@ -120,7 +124,6 @@ public:
|
||||||
Id getTypeId() const { return typeId; }
|
Id getTypeId() const { return typeId; }
|
||||||
Id getIdOperand(int op) const { return operands[op]; }
|
Id getIdOperand(int op) const { return operands[op]; }
|
||||||
unsigned int getImmediateOperand(int op) const { return operands[op]; }
|
unsigned int getImmediateOperand(int op) const { return operands[op]; }
|
||||||
const char* getStringOperand() const { return originalString.c_str(); }
|
|
||||||
|
|
||||||
// Write out the binary form.
|
// Write out the binary form.
|
||||||
void dump(std::vector<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
@ -151,7 +154,6 @@ protected:
|
||||||
Id typeId;
|
Id typeId;
|
||||||
Op opCode;
|
Op opCode;
|
||||||
std::vector<Id> operands;
|
std::vector<Id> operands;
|
||||||
std::string originalString; // could be optimized away; convenience for getting string operand
|
|
||||||
Block* block;
|
Block* block;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -256,7 +258,8 @@ public:
|
||||||
delete blocks[i];
|
delete blocks[i];
|
||||||
}
|
}
|
||||||
Id getId() const { return functionInstruction.getResultId(); }
|
Id getId() const { return functionInstruction.getResultId(); }
|
||||||
Id getParamId(int p) { return parameterInstructions[p]->getResultId(); }
|
Id getParamId(int p) const { return parameterInstructions[p]->getResultId(); }
|
||||||
|
Id getParamType(int p) const { return parameterInstructions[p]->getTypeId(); }
|
||||||
|
|
||||||
void addBlock(Block* block) { blocks.push_back(block); }
|
void addBlock(Block* block) { blocks.push_back(block); }
|
||||||
void removeBlock(Block* block)
|
void removeBlock(Block* block)
|
||||||
|
@ -273,6 +276,10 @@ public:
|
||||||
const std::vector<Block*>& getBlocks() const { return blocks; }
|
const std::vector<Block*>& getBlocks() const { return blocks; }
|
||||||
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||||
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||||
|
|
||||||
|
void setImplicitThis() { implicitThis = true; }
|
||||||
|
bool hasImplicitThis() const { return implicitThis; }
|
||||||
|
|
||||||
void dump(std::vector<unsigned int>& out) const
|
void dump(std::vector<unsigned int>& out) const
|
||||||
{
|
{
|
||||||
// OpFunction
|
// OpFunction
|
||||||
|
@ -296,6 +303,7 @@ protected:
|
||||||
Instruction functionInstruction;
|
Instruction functionInstruction;
|
||||||
std::vector<Instruction*> parameterInstructions;
|
std::vector<Instruction*> parameterInstructions;
|
||||||
std::vector<Block*> blocks;
|
std::vector<Block*> blocks;
|
||||||
|
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -354,7 +362,7 @@ protected:
|
||||||
// - the OpFunction instruction
|
// - the OpFunction instruction
|
||||||
// - all the OpFunctionParameter instructions
|
// - all the OpFunctionParameter instructions
|
||||||
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
||||||
: parent(parent), functionInstruction(id, resultType, OpFunction)
|
: parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false)
|
||||||
{
|
{
|
||||||
// OpFunction
|
// OpFunction
|
||||||
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
add_library(glslang-default-resource-limits
|
add_library(glslang-default-resource-limits
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp)
|
||||||
)
|
|
||||||
set_property(TARGET glslang-default-resource-limits PROPERTY FOLDER glslang)
|
set_property(TARGET glslang-default-resource-limits PROPERTY FOLDER glslang)
|
||||||
|
set_property(TARGET glslang-default-resource-limits PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
target_include_directories(glslang-default-resource-limits
|
target_include_directories(glslang-default-resource-limits
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
PUBLIC ${PROJECT_SOURCE_DIR}
|
PUBLIC ${PROJECT_SOURCE_DIR})
|
||||||
)
|
|
||||||
|
|
||||||
set(SOURCES StandAlone.cpp)
|
set(SOURCES StandAlone.cpp DirStackFileIncluder.h)
|
||||||
set(REMAPPER_SOURCES spirv-remap.cpp)
|
set(REMAPPER_SOURCES spirv-remap.cpp)
|
||||||
|
|
||||||
add_executable(glslangValidator ${SOURCES})
|
add_executable(glslangValidator ${SOURCES})
|
||||||
|
@ -20,10 +19,8 @@ glslang_set_link_args(spirv-remap)
|
||||||
|
|
||||||
set(LIBRARIES
|
set(LIBRARIES
|
||||||
glslang
|
glslang
|
||||||
OGLCompiler
|
|
||||||
OSDependent
|
|
||||||
HLSL
|
|
||||||
SPIRV
|
SPIRV
|
||||||
|
SPVRemapper
|
||||||
glslang-default-resource-limits)
|
glslang-default-resource-limits)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -41,8 +38,15 @@ if(WIN32)
|
||||||
source_group("Source" FILES ${SOURCES})
|
source_group("Source" FILES ${SOURCES})
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
install(TARGETS glslangValidator
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
RUNTIME DESTINATION bin)
|
install(TARGETS glslangValidator
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
install(TARGETS spirv-remap
|
install(TARGETS spirv-remap
|
||||||
RUNTIME DESTINATION bin)
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
if(BUILD_SHARED_LIBS)
|
||||||
|
install(TARGETS glslang-default-resource-limits
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif()
|
||||||
|
endif(ENABLE_GLSLANG_INSTALL)
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
// Copyright (C) 2017 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "./../glslang/Public/ShaderLang.h"
|
||||||
|
|
||||||
|
// Default include class for normal include convention of search backward
|
||||||
|
// through the stack of active include paths (for nested includes).
|
||||||
|
// Can be overridden to customize.
|
||||||
|
class DirStackFileIncluder : public glslang::TShader::Includer {
|
||||||
|
public:
|
||||||
|
DirStackFileIncluder() : externalLocalDirectoryCount(0) { }
|
||||||
|
|
||||||
|
virtual IncludeResult* includeLocal(const char* headerName,
|
||||||
|
const char* includerName,
|
||||||
|
size_t inclusionDepth) override
|
||||||
|
{
|
||||||
|
return readLocalPath(headerName, includerName, (int)inclusionDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual IncludeResult* includeSystem(const char* headerName,
|
||||||
|
const char* /*includerName*/,
|
||||||
|
size_t /*inclusionDepth*/) override
|
||||||
|
{
|
||||||
|
return readSystemPath(headerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Externally set directories. E.g., from a command-line -I<dir>.
|
||||||
|
// - Most-recently pushed are checked first.
|
||||||
|
// - All these are checked after the parse-time stack of local directories
|
||||||
|
// is checked.
|
||||||
|
// - This only applies to the "local" form of #include.
|
||||||
|
// - Makes its own copy of the path.
|
||||||
|
virtual void pushExternalLocalDirectory(const std::string& dir)
|
||||||
|
{
|
||||||
|
directoryStack.push_back(dir);
|
||||||
|
externalLocalDirectoryCount = (int)directoryStack.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void releaseInclude(IncludeResult* result) override
|
||||||
|
{
|
||||||
|
if (result != nullptr) {
|
||||||
|
delete [] static_cast<tUserDataElement*>(result->userData);
|
||||||
|
delete result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~DirStackFileIncluder() override { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef char tUserDataElement;
|
||||||
|
std::vector<std::string> directoryStack;
|
||||||
|
int externalLocalDirectoryCount;
|
||||||
|
|
||||||
|
// Search for a valid "local" path based on combining the stack of include
|
||||||
|
// directories and the nominal name of the header.
|
||||||
|
virtual IncludeResult* readLocalPath(const char* headerName, const char* includerName, int depth)
|
||||||
|
{
|
||||||
|
// Discard popped include directories, and
|
||||||
|
// initialize when at parse-time first level.
|
||||||
|
directoryStack.resize(depth + externalLocalDirectoryCount);
|
||||||
|
if (depth == 1)
|
||||||
|
directoryStack.back() = getDirectory(includerName);
|
||||||
|
|
||||||
|
// Find a directory that works, using a reverse search of the include stack.
|
||||||
|
for (auto it = directoryStack.rbegin(); it != directoryStack.rend(); ++it) {
|
||||||
|
std::string path = *it + '/' + headerName;
|
||||||
|
std::replace(path.begin(), path.end(), '\\', '/');
|
||||||
|
std::ifstream file(path, std::ios_base::binary | std::ios_base::ate);
|
||||||
|
if (file) {
|
||||||
|
directoryStack.push_back(getDirectory(path));
|
||||||
|
return newIncludeResult(path, file, (int)file.tellg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for a valid <system> path.
|
||||||
|
// Not implemented yet; returning nullptr signals failure to find.
|
||||||
|
virtual IncludeResult* readSystemPath(const char* /*headerName*/) const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do actual reading of the file, filling in a new include result.
|
||||||
|
virtual IncludeResult* newIncludeResult(const std::string& path, std::ifstream& file, int length) const
|
||||||
|
{
|
||||||
|
char* content = new tUserDataElement [length];
|
||||||
|
file.seekg(0, file.beg);
|
||||||
|
file.read(content, length);
|
||||||
|
return new IncludeResult(path, content, length, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no path markers, return current working directory.
|
||||||
|
// Otherwise, strip file name and return path leading up to it.
|
||||||
|
virtual std::string getDirectory(const std::string path) const
|
||||||
|
{
|
||||||
|
size_t last = path.find_last_of("/\\");
|
||||||
|
return last == std::string::npos ? "." : path.substr(0, last);
|
||||||
|
}
|
||||||
|
};
|
|
@ -35,6 +35,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
#include "ResourceLimits.h"
|
#include "ResourceLimits.h"
|
||||||
|
|
||||||
|
@ -240,205 +241,217 @@ std::string GetDefaultTBuiltInResourceString()
|
||||||
|
|
||||||
void DecodeResourceLimits(TBuiltInResource* resources, char* config)
|
void DecodeResourceLimits(TBuiltInResource* resources, char* config)
|
||||||
{
|
{
|
||||||
const char* delims = " \t\n\r";
|
static const char* delims = " \t\n\r";
|
||||||
const char* token = strtok(config, delims);
|
|
||||||
while (token) {
|
size_t pos = 0;
|
||||||
const char* valueStr = strtok(0, delims);
|
std::string configStr(config);
|
||||||
if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
|
|
||||||
printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
|
while ((pos = configStr.find_first_not_of(delims, pos)) != std::string::npos) {
|
||||||
|
const size_t token_s = pos;
|
||||||
|
const size_t token_e = configStr.find_first_of(delims, token_s);
|
||||||
|
const size_t value_s = configStr.find_first_not_of(delims, token_e);
|
||||||
|
const size_t value_e = configStr.find_first_of(delims, value_s);
|
||||||
|
pos = value_e;
|
||||||
|
|
||||||
|
// Faster to use compare(), but prefering readability.
|
||||||
|
const std::string tokenStr = configStr.substr(token_s, token_e-token_s);
|
||||||
|
const std::string valueStr = configStr.substr(value_s, value_e-value_s);
|
||||||
|
|
||||||
|
if (value_s == std::string::npos || ! (valueStr[0] == '-' || isdigit(valueStr[0]))) {
|
||||||
|
printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n",
|
||||||
|
valueStr.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int value = atoi(valueStr);
|
|
||||||
|
|
||||||
if (strcmp(token, "MaxLights") == 0)
|
const int value = std::atoi(valueStr.c_str());
|
||||||
|
|
||||||
|
if (tokenStr == "MaxLights")
|
||||||
resources->maxLights = value;
|
resources->maxLights = value;
|
||||||
else if (strcmp(token, "MaxClipPlanes") == 0)
|
else if (tokenStr == "MaxClipPlanes")
|
||||||
resources->maxClipPlanes = value;
|
resources->maxClipPlanes = value;
|
||||||
else if (strcmp(token, "MaxTextureUnits") == 0)
|
else if (tokenStr == "MaxTextureUnits")
|
||||||
resources->maxTextureUnits = value;
|
resources->maxTextureUnits = value;
|
||||||
else if (strcmp(token, "MaxTextureCoords") == 0)
|
else if (tokenStr == "MaxTextureCoords")
|
||||||
resources->maxTextureCoords = value;
|
resources->maxTextureCoords = value;
|
||||||
else if (strcmp(token, "MaxVertexAttribs") == 0)
|
else if (tokenStr == "MaxVertexAttribs")
|
||||||
resources->maxVertexAttribs = value;
|
resources->maxVertexAttribs = value;
|
||||||
else if (strcmp(token, "MaxVertexUniformComponents") == 0)
|
else if (tokenStr == "MaxVertexUniformComponents")
|
||||||
resources->maxVertexUniformComponents = value;
|
resources->maxVertexUniformComponents = value;
|
||||||
else if (strcmp(token, "MaxVaryingFloats") == 0)
|
else if (tokenStr == "MaxVaryingFloats")
|
||||||
resources->maxVaryingFloats = value;
|
resources->maxVaryingFloats = value;
|
||||||
else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
|
else if (tokenStr == "MaxVertexTextureImageUnits")
|
||||||
resources->maxVertexTextureImageUnits = value;
|
resources->maxVertexTextureImageUnits = value;
|
||||||
else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
|
else if (tokenStr == "MaxCombinedTextureImageUnits")
|
||||||
resources->maxCombinedTextureImageUnits = value;
|
resources->maxCombinedTextureImageUnits = value;
|
||||||
else if (strcmp(token, "MaxTextureImageUnits") == 0)
|
else if (tokenStr == "MaxTextureImageUnits")
|
||||||
resources->maxTextureImageUnits = value;
|
resources->maxTextureImageUnits = value;
|
||||||
else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
|
else if (tokenStr == "MaxFragmentUniformComponents")
|
||||||
resources->maxFragmentUniformComponents = value;
|
resources->maxFragmentUniformComponents = value;
|
||||||
else if (strcmp(token, "MaxDrawBuffers") == 0)
|
else if (tokenStr == "MaxDrawBuffers")
|
||||||
resources->maxDrawBuffers = value;
|
resources->maxDrawBuffers = value;
|
||||||
else if (strcmp(token, "MaxVertexUniformVectors") == 0)
|
else if (tokenStr == "MaxVertexUniformVectors")
|
||||||
resources->maxVertexUniformVectors = value;
|
resources->maxVertexUniformVectors = value;
|
||||||
else if (strcmp(token, "MaxVaryingVectors") == 0)
|
else if (tokenStr == "MaxVaryingVectors")
|
||||||
resources->maxVaryingVectors = value;
|
resources->maxVaryingVectors = value;
|
||||||
else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
|
else if (tokenStr == "MaxFragmentUniformVectors")
|
||||||
resources->maxFragmentUniformVectors = value;
|
resources->maxFragmentUniformVectors = value;
|
||||||
else if (strcmp(token, "MaxVertexOutputVectors") == 0)
|
else if (tokenStr == "MaxVertexOutputVectors")
|
||||||
resources->maxVertexOutputVectors = value;
|
resources->maxVertexOutputVectors = value;
|
||||||
else if (strcmp(token, "MaxFragmentInputVectors") == 0)
|
else if (tokenStr == "MaxFragmentInputVectors")
|
||||||
resources->maxFragmentInputVectors = value;
|
resources->maxFragmentInputVectors = value;
|
||||||
else if (strcmp(token, "MinProgramTexelOffset") == 0)
|
else if (tokenStr == "MinProgramTexelOffset")
|
||||||
resources->minProgramTexelOffset = value;
|
resources->minProgramTexelOffset = value;
|
||||||
else if (strcmp(token, "MaxProgramTexelOffset") == 0)
|
else if (tokenStr == "MaxProgramTexelOffset")
|
||||||
resources->maxProgramTexelOffset = value;
|
resources->maxProgramTexelOffset = value;
|
||||||
else if (strcmp(token, "MaxClipDistances") == 0)
|
else if (tokenStr == "MaxClipDistances")
|
||||||
resources->maxClipDistances = value;
|
resources->maxClipDistances = value;
|
||||||
else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
|
else if (tokenStr == "MaxComputeWorkGroupCountX")
|
||||||
resources->maxComputeWorkGroupCountX = value;
|
resources->maxComputeWorkGroupCountX = value;
|
||||||
else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
|
else if (tokenStr == "MaxComputeWorkGroupCountY")
|
||||||
resources->maxComputeWorkGroupCountY = value;
|
resources->maxComputeWorkGroupCountY = value;
|
||||||
else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
|
else if (tokenStr == "MaxComputeWorkGroupCountZ")
|
||||||
resources->maxComputeWorkGroupCountZ = value;
|
resources->maxComputeWorkGroupCountZ = value;
|
||||||
else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
|
else if (tokenStr == "MaxComputeWorkGroupSizeX")
|
||||||
resources->maxComputeWorkGroupSizeX = value;
|
resources->maxComputeWorkGroupSizeX = value;
|
||||||
else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
|
else if (tokenStr == "MaxComputeWorkGroupSizeY")
|
||||||
resources->maxComputeWorkGroupSizeY = value;
|
resources->maxComputeWorkGroupSizeY = value;
|
||||||
else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
|
else if (tokenStr == "MaxComputeWorkGroupSizeZ")
|
||||||
resources->maxComputeWorkGroupSizeZ = value;
|
resources->maxComputeWorkGroupSizeZ = value;
|
||||||
else if (strcmp(token, "MaxComputeUniformComponents") == 0)
|
else if (tokenStr == "MaxComputeUniformComponents")
|
||||||
resources->maxComputeUniformComponents = value;
|
resources->maxComputeUniformComponents = value;
|
||||||
else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
|
else if (tokenStr == "MaxComputeTextureImageUnits")
|
||||||
resources->maxComputeTextureImageUnits = value;
|
resources->maxComputeTextureImageUnits = value;
|
||||||
else if (strcmp(token, "MaxComputeImageUniforms") == 0)
|
else if (tokenStr == "MaxComputeImageUniforms")
|
||||||
resources->maxComputeImageUniforms = value;
|
resources->maxComputeImageUniforms = value;
|
||||||
else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
|
else if (tokenStr == "MaxComputeAtomicCounters")
|
||||||
resources->maxComputeAtomicCounters = value;
|
resources->maxComputeAtomicCounters = value;
|
||||||
else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
|
else if (tokenStr == "MaxComputeAtomicCounterBuffers")
|
||||||
resources->maxComputeAtomicCounterBuffers = value;
|
resources->maxComputeAtomicCounterBuffers = value;
|
||||||
else if (strcmp(token, "MaxVaryingComponents") == 0)
|
else if (tokenStr == "MaxVaryingComponents")
|
||||||
resources->maxVaryingComponents = value;
|
resources->maxVaryingComponents = value;
|
||||||
else if (strcmp(token, "MaxVertexOutputComponents") == 0)
|
else if (tokenStr == "MaxVertexOutputComponents")
|
||||||
resources->maxVertexOutputComponents = value;
|
resources->maxVertexOutputComponents = value;
|
||||||
else if (strcmp(token, "MaxGeometryInputComponents") == 0)
|
else if (tokenStr == "MaxGeometryInputComponents")
|
||||||
resources->maxGeometryInputComponents = value;
|
resources->maxGeometryInputComponents = value;
|
||||||
else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
|
else if (tokenStr == "MaxGeometryOutputComponents")
|
||||||
resources->maxGeometryOutputComponents = value;
|
resources->maxGeometryOutputComponents = value;
|
||||||
else if (strcmp(token, "MaxFragmentInputComponents") == 0)
|
else if (tokenStr == "MaxFragmentInputComponents")
|
||||||
resources->maxFragmentInputComponents = value;
|
resources->maxFragmentInputComponents = value;
|
||||||
else if (strcmp(token, "MaxImageUnits") == 0)
|
else if (tokenStr == "MaxImageUnits")
|
||||||
resources->maxImageUnits = value;
|
resources->maxImageUnits = value;
|
||||||
else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
|
else if (tokenStr == "MaxCombinedImageUnitsAndFragmentOutputs")
|
||||||
resources->maxCombinedImageUnitsAndFragmentOutputs = value;
|
resources->maxCombinedImageUnitsAndFragmentOutputs = value;
|
||||||
else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
|
else if (tokenStr == "MaxCombinedShaderOutputResources")
|
||||||
resources->maxCombinedShaderOutputResources = value;
|
resources->maxCombinedShaderOutputResources = value;
|
||||||
else if (strcmp(token, "MaxImageSamples") == 0)
|
else if (tokenStr == "MaxImageSamples")
|
||||||
resources->maxImageSamples = value;
|
resources->maxImageSamples = value;
|
||||||
else if (strcmp(token, "MaxVertexImageUniforms") == 0)
|
else if (tokenStr == "MaxVertexImageUniforms")
|
||||||
resources->maxVertexImageUniforms = value;
|
resources->maxVertexImageUniforms = value;
|
||||||
else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
|
else if (tokenStr == "MaxTessControlImageUniforms")
|
||||||
resources->maxTessControlImageUniforms = value;
|
resources->maxTessControlImageUniforms = value;
|
||||||
else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
|
else if (tokenStr == "MaxTessEvaluationImageUniforms")
|
||||||
resources->maxTessEvaluationImageUniforms = value;
|
resources->maxTessEvaluationImageUniforms = value;
|
||||||
else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
|
else if (tokenStr == "MaxGeometryImageUniforms")
|
||||||
resources->maxGeometryImageUniforms = value;
|
resources->maxGeometryImageUniforms = value;
|
||||||
else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
|
else if (tokenStr == "MaxFragmentImageUniforms")
|
||||||
resources->maxFragmentImageUniforms = value;
|
resources->maxFragmentImageUniforms = value;
|
||||||
else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
|
else if (tokenStr == "MaxCombinedImageUniforms")
|
||||||
resources->maxCombinedImageUniforms = value;
|
resources->maxCombinedImageUniforms = value;
|
||||||
else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
|
else if (tokenStr == "MaxGeometryTextureImageUnits")
|
||||||
resources->maxGeometryTextureImageUnits = value;
|
resources->maxGeometryTextureImageUnits = value;
|
||||||
else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
|
else if (tokenStr == "MaxGeometryOutputVertices")
|
||||||
resources->maxGeometryOutputVertices = value;
|
resources->maxGeometryOutputVertices = value;
|
||||||
else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
|
else if (tokenStr == "MaxGeometryTotalOutputComponents")
|
||||||
resources->maxGeometryTotalOutputComponents = value;
|
resources->maxGeometryTotalOutputComponents = value;
|
||||||
else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
|
else if (tokenStr == "MaxGeometryUniformComponents")
|
||||||
resources->maxGeometryUniformComponents = value;
|
resources->maxGeometryUniformComponents = value;
|
||||||
else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
|
else if (tokenStr == "MaxGeometryVaryingComponents")
|
||||||
resources->maxGeometryVaryingComponents = value;
|
resources->maxGeometryVaryingComponents = value;
|
||||||
else if (strcmp(token, "MaxTessControlInputComponents") == 0)
|
else if (tokenStr == "MaxTessControlInputComponents")
|
||||||
resources->maxTessControlInputComponents = value;
|
resources->maxTessControlInputComponents = value;
|
||||||
else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
|
else if (tokenStr == "MaxTessControlOutputComponents")
|
||||||
resources->maxTessControlOutputComponents = value;
|
resources->maxTessControlOutputComponents = value;
|
||||||
else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
|
else if (tokenStr == "MaxTessControlTextureImageUnits")
|
||||||
resources->maxTessControlTextureImageUnits = value;
|
resources->maxTessControlTextureImageUnits = value;
|
||||||
else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
|
else if (tokenStr == "MaxTessControlUniformComponents")
|
||||||
resources->maxTessControlUniformComponents = value;
|
resources->maxTessControlUniformComponents = value;
|
||||||
else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
|
else if (tokenStr == "MaxTessControlTotalOutputComponents")
|
||||||
resources->maxTessControlTotalOutputComponents = value;
|
resources->maxTessControlTotalOutputComponents = value;
|
||||||
else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
|
else if (tokenStr == "MaxTessEvaluationInputComponents")
|
||||||
resources->maxTessEvaluationInputComponents = value;
|
resources->maxTessEvaluationInputComponents = value;
|
||||||
else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
|
else if (tokenStr == "MaxTessEvaluationOutputComponents")
|
||||||
resources->maxTessEvaluationOutputComponents = value;
|
resources->maxTessEvaluationOutputComponents = value;
|
||||||
else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
|
else if (tokenStr == "MaxTessEvaluationTextureImageUnits")
|
||||||
resources->maxTessEvaluationTextureImageUnits = value;
|
resources->maxTessEvaluationTextureImageUnits = value;
|
||||||
else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
|
else if (tokenStr == "MaxTessEvaluationUniformComponents")
|
||||||
resources->maxTessEvaluationUniformComponents = value;
|
resources->maxTessEvaluationUniformComponents = value;
|
||||||
else if (strcmp(token, "MaxTessPatchComponents") == 0)
|
else if (tokenStr == "MaxTessPatchComponents")
|
||||||
resources->maxTessPatchComponents = value;
|
resources->maxTessPatchComponents = value;
|
||||||
else if (strcmp(token, "MaxPatchVertices") == 0)
|
else if (tokenStr == "MaxPatchVertices")
|
||||||
resources->maxPatchVertices = value;
|
resources->maxPatchVertices = value;
|
||||||
else if (strcmp(token, "MaxTessGenLevel") == 0)
|
else if (tokenStr == "MaxTessGenLevel")
|
||||||
resources->maxTessGenLevel = value;
|
resources->maxTessGenLevel = value;
|
||||||
else if (strcmp(token, "MaxViewports") == 0)
|
else if (tokenStr == "MaxViewports")
|
||||||
resources->maxViewports = value;
|
resources->maxViewports = value;
|
||||||
else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
|
else if (tokenStr == "MaxVertexAtomicCounters")
|
||||||
resources->maxVertexAtomicCounters = value;
|
resources->maxVertexAtomicCounters = value;
|
||||||
else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
|
else if (tokenStr == "MaxTessControlAtomicCounters")
|
||||||
resources->maxTessControlAtomicCounters = value;
|
resources->maxTessControlAtomicCounters = value;
|
||||||
else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
|
else if (tokenStr == "MaxTessEvaluationAtomicCounters")
|
||||||
resources->maxTessEvaluationAtomicCounters = value;
|
resources->maxTessEvaluationAtomicCounters = value;
|
||||||
else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
|
else if (tokenStr == "MaxGeometryAtomicCounters")
|
||||||
resources->maxGeometryAtomicCounters = value;
|
resources->maxGeometryAtomicCounters = value;
|
||||||
else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
|
else if (tokenStr == "MaxFragmentAtomicCounters")
|
||||||
resources->maxFragmentAtomicCounters = value;
|
resources->maxFragmentAtomicCounters = value;
|
||||||
else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
|
else if (tokenStr == "MaxCombinedAtomicCounters")
|
||||||
resources->maxCombinedAtomicCounters = value;
|
resources->maxCombinedAtomicCounters = value;
|
||||||
else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
|
else if (tokenStr == "MaxAtomicCounterBindings")
|
||||||
resources->maxAtomicCounterBindings = value;
|
resources->maxAtomicCounterBindings = value;
|
||||||
else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
|
else if (tokenStr == "MaxVertexAtomicCounterBuffers")
|
||||||
resources->maxVertexAtomicCounterBuffers = value;
|
resources->maxVertexAtomicCounterBuffers = value;
|
||||||
else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
|
else if (tokenStr == "MaxTessControlAtomicCounterBuffers")
|
||||||
resources->maxTessControlAtomicCounterBuffers = value;
|
resources->maxTessControlAtomicCounterBuffers = value;
|
||||||
else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
|
else if (tokenStr == "MaxTessEvaluationAtomicCounterBuffers")
|
||||||
resources->maxTessEvaluationAtomicCounterBuffers = value;
|
resources->maxTessEvaluationAtomicCounterBuffers = value;
|
||||||
else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
|
else if (tokenStr == "MaxGeometryAtomicCounterBuffers")
|
||||||
resources->maxGeometryAtomicCounterBuffers = value;
|
resources->maxGeometryAtomicCounterBuffers = value;
|
||||||
else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
|
else if (tokenStr == "MaxFragmentAtomicCounterBuffers")
|
||||||
resources->maxFragmentAtomicCounterBuffers = value;
|
resources->maxFragmentAtomicCounterBuffers = value;
|
||||||
else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
|
else if (tokenStr == "MaxCombinedAtomicCounterBuffers")
|
||||||
resources->maxCombinedAtomicCounterBuffers = value;
|
resources->maxCombinedAtomicCounterBuffers = value;
|
||||||
else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
|
else if (tokenStr == "MaxAtomicCounterBufferSize")
|
||||||
resources->maxAtomicCounterBufferSize = value;
|
resources->maxAtomicCounterBufferSize = value;
|
||||||
else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
|
else if (tokenStr == "MaxTransformFeedbackBuffers")
|
||||||
resources->maxTransformFeedbackBuffers = value;
|
resources->maxTransformFeedbackBuffers = value;
|
||||||
else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
|
else if (tokenStr == "MaxTransformFeedbackInterleavedComponents")
|
||||||
resources->maxTransformFeedbackInterleavedComponents = value;
|
resources->maxTransformFeedbackInterleavedComponents = value;
|
||||||
else if (strcmp(token, "MaxCullDistances") == 0)
|
else if (tokenStr == "MaxCullDistances")
|
||||||
resources->maxCullDistances = value;
|
resources->maxCullDistances = value;
|
||||||
else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
|
else if (tokenStr == "MaxCombinedClipAndCullDistances")
|
||||||
resources->maxCombinedClipAndCullDistances = value;
|
resources->maxCombinedClipAndCullDistances = value;
|
||||||
else if (strcmp(token, "MaxSamples") == 0)
|
else if (tokenStr == "MaxSamples")
|
||||||
resources->maxSamples = value;
|
resources->maxSamples = value;
|
||||||
|
else if (tokenStr == "nonInductiveForLoops")
|
||||||
else if (strcmp(token, "nonInductiveForLoops") == 0)
|
|
||||||
resources->limits.nonInductiveForLoops = (value != 0);
|
resources->limits.nonInductiveForLoops = (value != 0);
|
||||||
else if (strcmp(token, "whileLoops") == 0)
|
else if (tokenStr == "whileLoops")
|
||||||
resources->limits.whileLoops = (value != 0);
|
resources->limits.whileLoops = (value != 0);
|
||||||
else if (strcmp(token, "doWhileLoops") == 0)
|
else if (tokenStr == "doWhileLoops")
|
||||||
resources->limits.doWhileLoops = (value != 0);
|
resources->limits.doWhileLoops = (value != 0);
|
||||||
else if (strcmp(token, "generalUniformIndexing") == 0)
|
else if (tokenStr == "generalUniformIndexing")
|
||||||
resources->limits.generalUniformIndexing = (value != 0);
|
resources->limits.generalUniformIndexing = (value != 0);
|
||||||
else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
|
else if (tokenStr == "generalAttributeMatrixVectorIndexing")
|
||||||
resources->limits.generalAttributeMatrixVectorIndexing = (value != 0);
|
resources->limits.generalAttributeMatrixVectorIndexing = (value != 0);
|
||||||
else if (strcmp(token, "generalVaryingIndexing") == 0)
|
else if (tokenStr == "generalVaryingIndexing")
|
||||||
resources->limits.generalVaryingIndexing = (value != 0);
|
resources->limits.generalVaryingIndexing = (value != 0);
|
||||||
else if (strcmp(token, "generalSamplerIndexing") == 0)
|
else if (tokenStr == "generalSamplerIndexing")
|
||||||
resources->limits.generalSamplerIndexing = (value != 0);
|
resources->limits.generalSamplerIndexing = (value != 0);
|
||||||
else if (strcmp(token, "generalVariableIndexing") == 0)
|
else if (tokenStr == "generalVariableIndexing")
|
||||||
resources->limits.generalVariableIndexing = (value != 0);
|
resources->limits.generalVariableIndexing = (value != 0);
|
||||||
else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
|
else if (tokenStr == "generalConstantMatrixVectorIndexing")
|
||||||
resources->limits.generalConstantMatrixVectorIndexing = (value != 0);
|
resources->limits.generalConstantMatrixVectorIndexing = (value != 0);
|
||||||
else
|
else
|
||||||
printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
|
printf("Warning: unrecognized limit (%s) in configuration file.\n", tokenStr.c_str());
|
||||||
|
|
||||||
token = strtok(0, delims);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,25 +19,26 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
#ifndef WORKLIST_H_INCLUDED
|
#ifndef WORKLIST_H_INCLUDED
|
||||||
#define WORKLIST_H_INCLUDED
|
#define WORKLIST_H_INCLUDED
|
||||||
|
|
||||||
#include "../glslang/OSDependent/osinclude.h"
|
#include "../glslang/OSDependent/osinclude.h"
|
||||||
#include <string>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
@ -58,24 +59,19 @@ namespace glslang {
|
||||||
|
|
||||||
void add(TWorkItem* item)
|
void add(TWorkItem* item)
|
||||||
{
|
{
|
||||||
GetGlobalLock();
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
|
||||||
worklist.push_back(item);
|
worklist.push_back(item);
|
||||||
|
|
||||||
ReleaseGlobalLock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool remove(TWorkItem*& item)
|
bool remove(TWorkItem*& item)
|
||||||
{
|
{
|
||||||
GetGlobalLock();
|
std::lock_guard<std::mutex> guard(mutex);
|
||||||
|
|
||||||
if (worklist.empty())
|
if (worklist.empty())
|
||||||
return false;
|
return false;
|
||||||
item = worklist.front();
|
item = worklist.front();
|
||||||
worklist.pop_front();
|
worklist.pop_front();
|
||||||
|
|
||||||
ReleaseGlobalLock();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +86,7 @@ namespace glslang {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
std::mutex mutex;
|
||||||
std::list<TWorkItem*> worklist;
|
std::list<TWorkItem*> worklist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2015 LunarG, Inc.
|
// Copyright (C) 2015 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -311,7 +311,6 @@ namespace {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
std::vector<std::string> inputFile;
|
std::vector<std::string> inputFile;
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="glslang\GenericCodeGen\CodeGen.cpp" />
|
<ClCompile Include="glslang\GenericCodeGen\CodeGen.cpp" />
|
||||||
<ClCompile Include="glslang\GenericCodeGen\Link.cpp" />
|
<ClCompile Include="glslang\GenericCodeGen\Link.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\attribute.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\Constant.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\Constant.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\glslang_tab.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\InfoSink.cpp" />
|
||||||
|
@ -45,17 +46,17 @@
|
||||||
<ClCompile Include="glslang\MachineIndependent\Intermediate.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\Intermediate.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\intermOut.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\intermOut.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\IntermTraverse.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\IntermTraverse.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\iomapper.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\limits.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\limits.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\linkValidate.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\linkValidate.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\parseConst.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\parseConst.cpp" />
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\ParseContextBase.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\ParseHelper.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\ParseHelper.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\PoolAlloc.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\PoolAlloc.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\Pp.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\Pp.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpAtom.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpAtom.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpContext.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpContext.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpMemory.cpp" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpScanner.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpScanner.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpSymbols.cpp" />
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpTokens.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpTokens.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\propagateNoContraction.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\propagateNoContraction.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\reflection.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\reflection.cpp" />
|
||||||
|
@ -65,12 +66,6 @@
|
||||||
<ClCompile Include="glslang\MachineIndependent\SymbolTable.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\SymbolTable.cpp" />
|
||||||
<ClCompile Include="glslang\MachineIndependent\Versions.cpp" />
|
<ClCompile Include="glslang\MachineIndependent\Versions.cpp" />
|
||||||
<ClCompile Include="glslang\OSDependent\Windows\ossource.cpp" />
|
<ClCompile Include="glslang\OSDependent\Windows\ossource.cpp" />
|
||||||
<ClCompile Include="hlsl\hlslGrammar.cpp" />
|
|
||||||
<ClCompile Include="hlsl\hlslOpMap.cpp" />
|
|
||||||
<ClCompile Include="hlsl\hlslParseables.cpp" />
|
|
||||||
<ClCompile Include="hlsl\hlslParseHelper.cpp" />
|
|
||||||
<ClCompile Include="hlsl\hlslScanContext.cpp" />
|
|
||||||
<ClCompile Include="hlsl\hlslTokenStream.cpp" />
|
|
||||||
<ClCompile Include="OGLCompilersDLL\InitializeDll.cpp" />
|
<ClCompile Include="OGLCompilersDLL\InitializeDll.cpp" />
|
||||||
<ClCompile Include="SPIRV\disassemble.cpp" />
|
<ClCompile Include="SPIRV\disassemble.cpp" />
|
||||||
<ClCompile Include="SPIRV\doc.cpp" />
|
<ClCompile Include="SPIRV\doc.cpp" />
|
||||||
|
@ -93,9 +88,12 @@
|
||||||
<ClInclude Include="glslang\Include\revision.h" />
|
<ClInclude Include="glslang\Include\revision.h" />
|
||||||
<ClInclude Include="glslang\Include\ShHandle.h" />
|
<ClInclude Include="glslang\Include\ShHandle.h" />
|
||||||
<ClInclude Include="glslang\Include\Types.h" />
|
<ClInclude Include="glslang\Include\Types.h" />
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\attribute.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\glslang_tab.cpp.h" />
|
<ClInclude Include="glslang\MachineIndependent\glslang_tab.cpp.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\gl_types.h" />
|
<ClInclude Include="glslang\MachineIndependent\gl_types.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\Initialize.h" />
|
<ClInclude Include="glslang\MachineIndependent\Initialize.h" />
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\iomapper.h" />
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\LiveTraverser.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\localintermediate.h" />
|
<ClInclude Include="glslang\MachineIndependent\localintermediate.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\ParseHelper.h" />
|
<ClInclude Include="glslang\MachineIndependent\ParseHelper.h" />
|
||||||
<ClInclude Include="glslang\MachineIndependent\parseVersions.h" />
|
<ClInclude Include="glslang\MachineIndependent\parseVersions.h" />
|
||||||
|
@ -110,13 +108,6 @@
|
||||||
<ClInclude Include="glslang\MachineIndependent\Versions.h" />
|
<ClInclude Include="glslang\MachineIndependent\Versions.h" />
|
||||||
<ClInclude Include="glslang\OSDependent\osinclude.h" />
|
<ClInclude Include="glslang\OSDependent\osinclude.h" />
|
||||||
<ClInclude Include="glslang\Public\ShaderLang.h" />
|
<ClInclude Include="glslang\Public\ShaderLang.h" />
|
||||||
<ClInclude Include="hlsl\hlslGrammar.h" />
|
|
||||||
<ClInclude Include="hlsl\hlslOpMap.h" />
|
|
||||||
<ClInclude Include="hlsl\hlslParseables.h" />
|
|
||||||
<ClInclude Include="hlsl\hlslParseHelper.h" />
|
|
||||||
<ClInclude Include="hlsl\hlslScanContext.h" />
|
|
||||||
<ClInclude Include="hlsl\hlslTokens.h" />
|
|
||||||
<ClInclude Include="hlsl\hlslTokenStream.h" />
|
|
||||||
<ClInclude Include="OGLCompilersDLL\InitializeDll.h" />
|
<ClInclude Include="OGLCompilersDLL\InitializeDll.h" />
|
||||||
<ClInclude Include="SPIRV\disassemble.h" />
|
<ClInclude Include="SPIRV\disassemble.h" />
|
||||||
<ClInclude Include="SPIRV\doc.h" />
|
<ClInclude Include="SPIRV\doc.h" />
|
||||||
|
|
|
@ -7,15 +7,9 @@
|
||||||
<ClCompile Include="glslang\GenericCodeGen\CodeGen.cpp">
|
<ClCompile Include="glslang\GenericCodeGen\CodeGen.cpp">
|
||||||
<Filter>glslang\GenericCodeGen</Filter>
|
<Filter>glslang\GenericCodeGen</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpMemory.cpp">
|
|
||||||
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpScanner.cpp">
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpScanner.cpp">
|
||||||
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpSymbols.cpp">
|
|
||||||
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpTokens.cpp">
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpTokens.cpp">
|
||||||
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -28,6 +22,9 @@
|
||||||
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpContext.cpp">
|
<ClCompile Include="glslang\MachineIndependent\preprocessor\PpContext.cpp">
|
||||||
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="glslang\MachineIndependent\attribute.cpp">
|
||||||
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="glslang\MachineIndependent\linkValidate.cpp">
|
<ClCompile Include="glslang\MachineIndependent\linkValidate.cpp">
|
||||||
<Filter>glslang\MachineIndependant</Filter>
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -112,23 +109,11 @@
|
||||||
<ClCompile Include="OGLCompilersDLL\InitializeDll.cpp">
|
<ClCompile Include="OGLCompilersDLL\InitializeDll.cpp">
|
||||||
<Filter>OGLCompilersDLL</Filter>
|
<Filter>OGLCompilersDLL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="hlsl\hlslGrammar.cpp">
|
<ClCompile Include="glslang\MachineIndependent\iomapper.cpp">
|
||||||
<Filter>hlsl</Filter>
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="hlsl\hlslOpMap.cpp">
|
<ClCompile Include="glslang\MachineIndependent\ParseContextBase.cpp">
|
||||||
<Filter>hlsl</Filter>
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="hlsl\hlslParseHelper.cpp">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="hlsl\hlslScanContext.cpp">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="hlsl\hlslTokenStream.cpp">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="hlsl\hlslParseables.cpp">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -174,6 +159,9 @@
|
||||||
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpContext.h">
|
<ClInclude Include="glslang\MachineIndependent\preprocessor\PpContext.h">
|
||||||
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
<Filter>glslang\MachineIndependant\preprocessor</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="glslang\MachineIndependent\attribute.h">
|
||||||
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="glslang\MachineIndependent\localintermediate.h">
|
<ClInclude Include="glslang\MachineIndependent\localintermediate.h">
|
||||||
<Filter>glslang\MachineIndependant</Filter>
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -249,26 +237,11 @@
|
||||||
<ClInclude Include="OGLCompilersDLL\InitializeDll.h">
|
<ClInclude Include="OGLCompilersDLL\InitializeDll.h">
|
||||||
<Filter>OGLCompilersDLL</Filter>
|
<Filter>OGLCompilersDLL</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="hlsl\hlslGrammar.h">
|
<ClInclude Include="glslang\MachineIndependent\iomapper.h">
|
||||||
<Filter>hlsl</Filter>
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="hlsl\hlslOpMap.h">
|
<ClInclude Include="glslang\MachineIndependent\LiveTraverser.h">
|
||||||
<Filter>hlsl</Filter>
|
<Filter>glslang\MachineIndependant</Filter>
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="hlsl\hlslParseHelper.h">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="hlsl\hlslScanContext.h">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="hlsl\hlslTokens.h">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="hlsl\hlslTokenStream.h">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="hlsl\hlslParseables.h">
|
|
||||||
<Filter>hlsl</Filter>
|
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -299,9 +272,6 @@
|
||||||
<Filter Include="SPIRV">
|
<Filter Include="SPIRV">
|
||||||
<UniqueIdentifier>{7039de2e-63ef-409d-a895-3c0dd307e201}</UniqueIdentifier>
|
<UniqueIdentifier>{7039de2e-63ef-409d-a895-3c0dd307e201}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="hlsl">
|
|
||||||
<UniqueIdentifier>{e465129b-44ff-46e1-b876-76c529f3a945}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="OGLCompilersDLL">
|
<Filter Include="OGLCompilersDLL">
|
||||||
<UniqueIdentifier>{8d950cfc-7fb5-4612-b23c-f4d569404955}</UniqueIdentifier>
|
<UniqueIdentifier>{8d950cfc-7fb5-4612-b23c-f4d569404955}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
|
|
@ -9,11 +9,14 @@ endif(WIN32)
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
MachineIndependent/glslang.y
|
MachineIndependent/glslang.y
|
||||||
MachineIndependent/glslang_tab.cpp
|
MachineIndependent/glslang_tab.cpp
|
||||||
|
MachineIndependent/attribute.cpp
|
||||||
MachineIndependent/Constant.cpp
|
MachineIndependent/Constant.cpp
|
||||||
|
MachineIndependent/iomapper.cpp
|
||||||
MachineIndependent/InfoSink.cpp
|
MachineIndependent/InfoSink.cpp
|
||||||
MachineIndependent/Initialize.cpp
|
MachineIndependent/Initialize.cpp
|
||||||
MachineIndependent/IntermTraverse.cpp
|
MachineIndependent/IntermTraverse.cpp
|
||||||
MachineIndependent/Intermediate.cpp
|
MachineIndependent/Intermediate.cpp
|
||||||
|
MachineIndependent/ParseContextBase.cpp
|
||||||
MachineIndependent/ParseHelper.cpp
|
MachineIndependent/ParseHelper.cpp
|
||||||
MachineIndependent/PoolAlloc.cpp
|
MachineIndependent/PoolAlloc.cpp
|
||||||
MachineIndependent/RemoveTree.cpp
|
MachineIndependent/RemoveTree.cpp
|
||||||
|
@ -29,9 +32,7 @@ set(SOURCES
|
||||||
MachineIndependent/preprocessor/Pp.cpp
|
MachineIndependent/preprocessor/Pp.cpp
|
||||||
MachineIndependent/preprocessor/PpAtom.cpp
|
MachineIndependent/preprocessor/PpAtom.cpp
|
||||||
MachineIndependent/preprocessor/PpContext.cpp
|
MachineIndependent/preprocessor/PpContext.cpp
|
||||||
MachineIndependent/preprocessor/PpMemory.cpp
|
|
||||||
MachineIndependent/preprocessor/PpScanner.cpp
|
MachineIndependent/preprocessor/PpScanner.cpp
|
||||||
MachineIndependent/preprocessor/PpSymbols.cpp
|
|
||||||
MachineIndependent/preprocessor/PpTokens.cpp
|
MachineIndependent/preprocessor/PpTokens.cpp
|
||||||
MachineIndependent/propagateNoContraction.cpp
|
MachineIndependent/propagateNoContraction.cpp
|
||||||
GenericCodeGen/CodeGen.cpp
|
GenericCodeGen/CodeGen.cpp
|
||||||
|
@ -51,9 +52,12 @@ set(HEADERS
|
||||||
Include/revision.h
|
Include/revision.h
|
||||||
Include/ShHandle.h
|
Include/ShHandle.h
|
||||||
Include/Types.h
|
Include/Types.h
|
||||||
|
MachineIndependent/attribute.h
|
||||||
MachineIndependent/glslang_tab.cpp.h
|
MachineIndependent/glslang_tab.cpp.h
|
||||||
MachineIndependent/gl_types.h
|
MachineIndependent/gl_types.h
|
||||||
MachineIndependent/Initialize.h
|
MachineIndependent/Initialize.h
|
||||||
|
MachineIndependent/iomapper.h
|
||||||
|
MachineIndependent/LiveTraverser.h
|
||||||
MachineIndependent/localintermediate.h
|
MachineIndependent/localintermediate.h
|
||||||
MachineIndependent/ParseHelper.h
|
MachineIndependent/ParseHelper.h
|
||||||
MachineIndependent/reflection.h
|
MachineIndependent/reflection.h
|
||||||
|
@ -76,8 +80,19 @@ set(HEADERS
|
||||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
# set(BISON_GLSLParser_OUTPUT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp)
|
# set(BISON_GLSLParser_OUTPUT_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/MachineIndependent/glslang_tab.cpp)
|
||||||
|
|
||||||
add_library(glslang STATIC ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS})
|
add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS})
|
||||||
set_property(TARGET glslang PROPERTY FOLDER glslang)
|
set_property(TARGET glslang PROPERTY FOLDER glslang)
|
||||||
|
set_property(TARGET glslang PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
target_link_libraries(glslang OGLCompiler OSDependent)
|
||||||
|
target_include_directories(glslang PUBLIC ..)
|
||||||
|
|
||||||
|
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||||
|
set_target_properties(glslang PROPERTIES PREFIX "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_HLSL)
|
||||||
|
target_link_libraries(glslang HLSL)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
source_group("Public" REGULAR_EXPRESSION "Public/*")
|
source_group("Public" REGULAR_EXPRESSION "Public/*")
|
||||||
|
@ -87,5 +102,20 @@ if(WIN32)
|
||||||
source_group("MachineIndependent\\Preprocessor" REGULAR_EXPRESSION "MachineIndependent/preprocessor/*")
|
source_group("MachineIndependent\\Preprocessor" REGULAR_EXPRESSION "MachineIndependent/preprocessor/*")
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
install(TARGETS glslang
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
ARCHIVE DESTINATION lib)
|
if(BUILD_SHARED_LIBS)
|
||||||
|
install(TARGETS glslang
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
else()
|
||||||
|
install(TARGETS glslang
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif()
|
||||||
|
endif(ENABLE_GLSLANG_INSTALL)
|
||||||
|
|
||||||
|
if(ENABLE_GLSLANG_INSTALL)
|
||||||
|
foreach(file ${HEADERS})
|
||||||
|
get_filename_component(dir ${file} DIRECTORY)
|
||||||
|
install(FILES ${file} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang/${dir})
|
||||||
|
endforeach()
|
||||||
|
endif(ENABLE_GLSLANG_INSTALL)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +21,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _BASICTYPES_INCLUDED_
|
#ifndef _BASICTYPES_INCLUDED_
|
||||||
|
@ -46,6 +47,11 @@ enum TBasicType {
|
||||||
EbtVoid,
|
EbtVoid,
|
||||||
EbtFloat,
|
EbtFloat,
|
||||||
EbtDouble,
|
EbtDouble,
|
||||||
|
EbtFloat16,
|
||||||
|
EbtInt8,
|
||||||
|
EbtUint8,
|
||||||
|
EbtInt16,
|
||||||
|
EbtUint16,
|
||||||
EbtInt,
|
EbtInt,
|
||||||
EbtUint,
|
EbtUint,
|
||||||
EbtInt64,
|
EbtInt64,
|
||||||
|
@ -55,6 +61,10 @@ enum TBasicType {
|
||||||
EbtSampler,
|
EbtSampler,
|
||||||
EbtStruct,
|
EbtStruct,
|
||||||
EbtBlock,
|
EbtBlock,
|
||||||
|
|
||||||
|
// HLSL types that live only temporarily.
|
||||||
|
EbtString,
|
||||||
|
|
||||||
EbtNumTypes
|
EbtNumTypes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -130,6 +140,8 @@ enum TBuiltInVariable {
|
||||||
EbvLocalInvocationId,
|
EbvLocalInvocationId,
|
||||||
EbvGlobalInvocationId,
|
EbvGlobalInvocationId,
|
||||||
EbvLocalInvocationIndex,
|
EbvLocalInvocationIndex,
|
||||||
|
EbvNumSubgroups,
|
||||||
|
EbvSubgroupID,
|
||||||
EbvSubGroupSize,
|
EbvSubGroupSize,
|
||||||
EbvSubGroupInvocation,
|
EbvSubGroupInvocation,
|
||||||
EbvSubGroupEqMask,
|
EbvSubGroupEqMask,
|
||||||
|
@ -137,6 +149,13 @@ enum TBuiltInVariable {
|
||||||
EbvSubGroupGtMask,
|
EbvSubGroupGtMask,
|
||||||
EbvSubGroupLeMask,
|
EbvSubGroupLeMask,
|
||||||
EbvSubGroupLtMask,
|
EbvSubGroupLtMask,
|
||||||
|
EbvSubgroupSize2,
|
||||||
|
EbvSubgroupInvocation2,
|
||||||
|
EbvSubgroupEqMask2,
|
||||||
|
EbvSubgroupGeMask2,
|
||||||
|
EbvSubgroupGtMask2,
|
||||||
|
EbvSubgroupLeMask2,
|
||||||
|
EbvSubgroupLtMask2,
|
||||||
EbvVertexId,
|
EbvVertexId,
|
||||||
EbvInstanceId,
|
EbvInstanceId,
|
||||||
EbvVertexIndex,
|
EbvVertexIndex,
|
||||||
|
@ -182,11 +201,49 @@ enum TBuiltInVariable {
|
||||||
EbvFragColor,
|
EbvFragColor,
|
||||||
EbvFragData,
|
EbvFragData,
|
||||||
EbvFragDepth,
|
EbvFragDepth,
|
||||||
|
EbvFragStencilRef,
|
||||||
EbvSampleId,
|
EbvSampleId,
|
||||||
EbvSamplePosition,
|
EbvSamplePosition,
|
||||||
EbvSampleMask,
|
EbvSampleMask,
|
||||||
EbvHelperInvocation,
|
EbvHelperInvocation,
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EbvBaryCoordNoPersp,
|
||||||
|
EbvBaryCoordNoPerspCentroid,
|
||||||
|
EbvBaryCoordNoPerspSample,
|
||||||
|
EbvBaryCoordSmooth,
|
||||||
|
EbvBaryCoordSmoothCentroid,
|
||||||
|
EbvBaryCoordSmoothSample,
|
||||||
|
EbvBaryCoordPullModel,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EbvViewIndex,
|
||||||
|
EbvDeviceIndex,
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
EbvViewportMaskNV,
|
||||||
|
EbvSecondaryPositionNV,
|
||||||
|
EbvSecondaryViewportMaskNV,
|
||||||
|
EbvPositionPerViewNV,
|
||||||
|
EbvViewportMaskPerViewNV,
|
||||||
|
EbvFragFullyCoveredNV,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// HLSL built-ins that live only temporarily, until they get remapped
|
||||||
|
// to one of the above.
|
||||||
|
EbvFragDepthGreater,
|
||||||
|
EbvFragDepthLesser,
|
||||||
|
EbvGsOutputStream,
|
||||||
|
EbvOutputPatch,
|
||||||
|
EbvInputPatch,
|
||||||
|
|
||||||
|
// structbuffer types
|
||||||
|
EbvAppendConsume, // no need to differentiate append and consume
|
||||||
|
EbvRWStructuredBuffer,
|
||||||
|
EbvStructuredBuffer,
|
||||||
|
EbvByteAddressBuffer,
|
||||||
|
EbvRWByteAddressBuffer,
|
||||||
|
|
||||||
EbvLast
|
EbvLast
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -282,10 +339,33 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||||
case EbvFragColor: return "FragColor";
|
case EbvFragColor: return "FragColor";
|
||||||
case EbvFragData: return "FragData";
|
case EbvFragData: return "FragData";
|
||||||
case EbvFragDepth: return "FragDepth";
|
case EbvFragDepth: return "FragDepth";
|
||||||
|
case EbvFragStencilRef: return "FragStencilRef";
|
||||||
case EbvSampleId: return "SampleId";
|
case EbvSampleId: return "SampleId";
|
||||||
case EbvSamplePosition: return "SamplePosition";
|
case EbvSamplePosition: return "SamplePosition";
|
||||||
case EbvSampleMask: return "SampleMaskIn";
|
case EbvSampleMask: return "SampleMaskIn";
|
||||||
case EbvHelperInvocation: return "HelperInvocation";
|
case EbvHelperInvocation: return "HelperInvocation";
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbvBaryCoordNoPersp: return "BaryCoordNoPersp";
|
||||||
|
case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid";
|
||||||
|
case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample";
|
||||||
|
case EbvBaryCoordSmooth: return "BaryCoordSmooth";
|
||||||
|
case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid";
|
||||||
|
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
||||||
|
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case EbvViewIndex: return "ViewIndex";
|
||||||
|
case EbvDeviceIndex: return "DeviceIndex";
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EbvViewportMaskNV: return "ViewportMaskNV";
|
||||||
|
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
|
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
|
case EbvPositionPerViewNV: return "PositionPerViewNV";
|
||||||
|
case EbvViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
|
case EbvFragFullyCoveredNV: return "FragFullyCoveredNV";
|
||||||
|
#endif
|
||||||
default: return "unknown built-in variable";
|
default: return "unknown built-in variable";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,7 +381,7 @@ enum TPrecisionQualifier {
|
||||||
|
|
||||||
__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
||||||
{
|
{
|
||||||
switch(p) {
|
switch (p) {
|
||||||
case EpqNone: return ""; break;
|
case EpqNone: return ""; break;
|
||||||
case EpqLow: return "lowp"; break;
|
case EpqLow: return "lowp"; break;
|
||||||
case EpqMedium: return "mediump"; break;
|
case EpqMedium: return "mediump"; break;
|
||||||
|
@ -310,6 +390,75 @@ __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__inline bool isTypeSignedInt(TBasicType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case EbtInt8:
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtInt:
|
||||||
|
case EbtInt64:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline bool isTypeUnsignedInt(TBasicType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case EbtUint8:
|
||||||
|
case EbtUint16:
|
||||||
|
case EbtUint:
|
||||||
|
case EbtUint64:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline bool isTypeInt(TBasicType type)
|
||||||
|
{
|
||||||
|
return isTypeSignedInt(type) || isTypeUnsignedInt(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline bool isTypeFloat(TBasicType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case EbtFloat:
|
||||||
|
case EbtDouble:
|
||||||
|
case EbtFloat16:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline int getTypeRank(TBasicType type) {
|
||||||
|
int res = -1;
|
||||||
|
switch(type) {
|
||||||
|
case EbtInt8:
|
||||||
|
case EbtUint8:
|
||||||
|
res = 0;
|
||||||
|
break;
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16:
|
||||||
|
res = 1;
|
||||||
|
break;
|
||||||
|
case EbtInt:
|
||||||
|
case EbtUint:
|
||||||
|
res = 2;
|
||||||
|
break;
|
||||||
|
case EbtInt64:
|
||||||
|
case EbtUint64:
|
||||||
|
res = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _BASICTYPES_INCLUDED_
|
#endif // _BASICTYPES_INCLUDED_
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,36 +20,23 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _COMMON_INCLUDED_
|
#ifndef _COMMON_INCLUDED_
|
||||||
#define _COMMON_INCLUDED_
|
#define _COMMON_INCLUDED_
|
||||||
|
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
|
|
||||||
#include <basetsd.h>
|
|
||||||
#define snprintf sprintf_s
|
|
||||||
#define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args))
|
|
||||||
#elif defined (solaris)
|
|
||||||
#define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
|
|
||||||
#include <sys/int_types.h>
|
|
||||||
#define UINT_PTR uintptr_t
|
|
||||||
#else
|
|
||||||
#define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
|
|
||||||
#include <stdint.h>
|
|
||||||
#define UINT_PTR uintptr_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__ANDROID__) || _MSC_VER < 1700
|
#if defined(__ANDROID__) || _MSC_VER < 1700
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -63,15 +50,40 @@ std::string to_string(const T& val) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1700
|
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
|
||||||
inline long long int strtoll (const char* str, char** endptr, int base)
|
#include <basetsd.h>
|
||||||
{
|
#ifndef snprintf
|
||||||
|
#define snprintf sprintf_s
|
||||||
|
#endif
|
||||||
|
#define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args))
|
||||||
|
#elif defined (solaris)
|
||||||
|
#define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
|
||||||
|
#include <sys/int_types.h>
|
||||||
|
#define UINT_PTR uintptr_t
|
||||||
|
#else
|
||||||
|
#define safe_vsprintf(buf,max,format,args) vsnprintf((buf), (max), (format), (args))
|
||||||
|
#include <stdint.h>
|
||||||
|
#define UINT_PTR uintptr_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1800
|
||||||
|
#include <stdlib.h>
|
||||||
|
inline long long int strtoll (const char* str, char** endptr, int base)
|
||||||
|
{
|
||||||
return _strtoi64(str, endptr, base);
|
return _strtoi64(str, endptr, base);
|
||||||
}
|
}
|
||||||
inline long long int atoll (const char* str)
|
inline unsigned long long int strtoull (const char* str, char** endptr, int base)
|
||||||
{
|
{
|
||||||
|
return _strtoui64(str, endptr, base);
|
||||||
|
}
|
||||||
|
inline long long int atoll (const char* str)
|
||||||
|
{
|
||||||
return strtoll(str, NULL, 10);
|
return strtoll(str, NULL, 10);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define strdup _strdup
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* windows only pragma */
|
/* windows only pragma */
|
||||||
|
@ -89,8 +101,8 @@ inline long long int atoll (const char* str)
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
|
|
||||||
#include "PoolAlloc.h"
|
#include "PoolAlloc.h"
|
||||||
|
|
||||||
|
@ -147,7 +159,7 @@ inline TString* NewPoolTString(const char* s)
|
||||||
return new(memory) TString(s);
|
return new(memory) TString(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> inline T* NewPoolObject(T)
|
template<class T> inline T* NewPoolObject(T*)
|
||||||
{
|
{
|
||||||
return new(GetThreadPoolAllocator().allocate(sizeof(T))) T;
|
return new(GetThreadPoolAllocator().allocate(sizeof(T))) T;
|
||||||
}
|
}
|
||||||
|
@ -197,22 +209,28 @@ template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
|
||||||
//
|
//
|
||||||
// Create a TString object from an integer.
|
// Create a TString object from an integer.
|
||||||
//
|
//
|
||||||
|
#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
|
||||||
inline const TString String(const int i, const int base = 10)
|
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
|
char text[16]; // 32 bit ints are at most 10 digits in base 10
|
||||||
|
|
||||||
#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
|
|
||||||
_itoa_s(i, text, sizeof(text), base);
|
_itoa_s(i, text, sizeof(text), base);
|
||||||
#else
|
return text;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
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
|
||||||
|
|
||||||
// we assume base 10 for all cases
|
// we assume base 10 for all cases
|
||||||
snprintf(text, sizeof(text), "%d", i);
|
snprintf(text, sizeof(text), "%d", i);
|
||||||
#endif
|
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct TSourceLoc {
|
struct TSourceLoc {
|
||||||
void init() { name = nullptr; string = 0; line = 0; column = 0; }
|
void init() { name = nullptr; string = 0; line = 0; column = 0; }
|
||||||
|
void init(int stringNum) { init(); string = stringNum; }
|
||||||
// Returns the name if it exists. Otherwise, returns the string number.
|
// Returns the name if it exists. Otherwise, returns the string number.
|
||||||
std::string getStringNameOrNum(bool quoteStringName = true) const
|
std::string getStringNameOrNum(bool quoteStringName = true) const
|
||||||
{
|
{
|
||||||
|
@ -226,7 +244,10 @@ struct TSourceLoc {
|
||||||
int column;
|
int column;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TMap<TString, TString> TPragmaTable;
|
class TPragmaTable : public TMap<TString, TString> {
|
||||||
|
public:
|
||||||
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
|
};
|
||||||
|
|
||||||
const int MaxTokenLength = 1024;
|
const int MaxTokenLength = 1024;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,23 +21,26 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _CONSTANT_UNION_INCLUDED_
|
#ifndef _CONSTANT_UNION_INCLUDED_
|
||||||
#define _CONSTANT_UNION_INCLUDED_
|
#define _CONSTANT_UNION_INCLUDED_
|
||||||
|
|
||||||
|
#include "../Include/Common.h"
|
||||||
|
#include "../Include/BaseTypes.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
class TConstUnion {
|
class TConstUnion {
|
||||||
|
@ -45,6 +49,30 @@ public:
|
||||||
|
|
||||||
TConstUnion() : iConst(0), type(EbtInt) { }
|
TConstUnion() : iConst(0), type(EbtInt) { }
|
||||||
|
|
||||||
|
void setI8Const(signed char i)
|
||||||
|
{
|
||||||
|
i8Const = i;
|
||||||
|
type = EbtInt8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setU8Const(unsigned char u)
|
||||||
|
{
|
||||||
|
u8Const = u;
|
||||||
|
type = EbtUint8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setI16Const(signed short i)
|
||||||
|
{
|
||||||
|
i16Const = i;
|
||||||
|
type = EbtInt16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setU16Const(unsigned short u)
|
||||||
|
{
|
||||||
|
u16Const = u;
|
||||||
|
type = EbtUint16;
|
||||||
|
}
|
||||||
|
|
||||||
void setIConst(int i)
|
void setIConst(int i)
|
||||||
{
|
{
|
||||||
iConst = i;
|
iConst = i;
|
||||||
|
@ -81,12 +109,55 @@ public:
|
||||||
type = EbtBool;
|
type = EbtBool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSConst(const TString* s)
|
||||||
|
{
|
||||||
|
sConst = s;
|
||||||
|
type = EbtString;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char getI8Const() const { return i8Const; }
|
||||||
|
unsigned char getU8Const() const { return u8Const; }
|
||||||
|
signed short getI16Const() const { return i16Const; }
|
||||||
|
unsigned short getU16Const() const { return u16Const; }
|
||||||
int getIConst() const { return iConst; }
|
int getIConst() const { return iConst; }
|
||||||
unsigned int getUConst() const { return uConst; }
|
unsigned int getUConst() const { return uConst; }
|
||||||
long long getI64Const() const { return i64Const; }
|
long long getI64Const() const { return i64Const; }
|
||||||
unsigned long long getU64Const() const { return u64Const; }
|
unsigned long long getU64Const() const { return u64Const; }
|
||||||
double getDConst() const { return dConst; }
|
double getDConst() const { return dConst; }
|
||||||
bool getBConst() const { return bConst; }
|
bool getBConst() const { return bConst; }
|
||||||
|
const TString* getSConst() const { return sConst; }
|
||||||
|
|
||||||
|
bool operator==(const signed char i) const
|
||||||
|
{
|
||||||
|
if (i == i8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const unsigned char u) const
|
||||||
|
{
|
||||||
|
if (u == u8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const signed short i) const
|
||||||
|
{
|
||||||
|
if (i == i16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const unsigned short u) const
|
||||||
|
{
|
||||||
|
if (u == u16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const int i) const
|
bool operator==(const int i) const
|
||||||
{
|
{
|
||||||
|
@ -142,6 +213,26 @@ public:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt16:
|
||||||
|
if (constant.i16Const == i16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
if (constant.u16Const == u16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EbtInt8:
|
||||||
|
if (constant.i8Const == i8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EbtUint8:
|
||||||
|
if (constant.u8Const == u8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
if (constant.iConst == iConst)
|
if (constant.iConst == iConst)
|
||||||
return true;
|
return true;
|
||||||
|
@ -179,6 +270,26 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator!=(const signed char i) const
|
||||||
|
{
|
||||||
|
return !operator==(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const unsigned char u) const
|
||||||
|
{
|
||||||
|
return !operator==(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const signed short i) const
|
||||||
|
{
|
||||||
|
return !operator==(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const unsigned short u) const
|
||||||
|
{
|
||||||
|
return !operator==(u);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator!=(const int i) const
|
bool operator!=(const int i) const
|
||||||
{
|
{
|
||||||
return !operator==(i);
|
return !operator==(i);
|
||||||
|
@ -218,6 +329,26 @@ public:
|
||||||
{
|
{
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8:
|
||||||
|
if (i8Const > constant.i8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtUint8:
|
||||||
|
if (u8Const > constant.u8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtInt16:
|
||||||
|
if (i16Const > constant.i16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtUint16:
|
||||||
|
if (u16Const > constant.u16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
if (iConst > constant.iConst)
|
if (iConst > constant.iConst)
|
||||||
return true;
|
return true;
|
||||||
|
@ -253,6 +384,26 @@ public:
|
||||||
{
|
{
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8:
|
||||||
|
if (i8Const < constant.i8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtUint8:
|
||||||
|
if (u8Const < constant.u8Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtInt16:
|
||||||
|
if (i16Const < constant.i16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtUint16:
|
||||||
|
if (u16Const < constant.u16Const)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
if (iConst < constant.iConst)
|
if (iConst < constant.iConst)
|
||||||
return true;
|
return true;
|
||||||
|
@ -289,8 +440,12 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
|
case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
|
||||||
|
@ -305,8 +460,12 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
|
case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
|
||||||
|
@ -321,8 +480,12 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
||||||
|
@ -337,8 +500,12 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
|
@ -351,8 +518,64 @@ public:
|
||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setI8Const(i8Const >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI8Const(i8Const >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setI8Const(i8Const >> constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setI8Const(i8Const >> constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setI8Const(i8Const >> constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setI8Const(i8Const >> constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setI8Const(i8Const >> constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint8:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setU8Const(u8Const >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setU8Const(u8Const >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU8Const(u8Const >> constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setU8Const(u8Const >> constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setU8Const(u8Const >> constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setU8Const(u8Const >> constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setU8Const(u8Const >> constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtInt16:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setI16Const(i16Const >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setI16Const(i16Const >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setI16Const(i16Const >> constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setI16Const(i16Const >> constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setI16Const(i16Const >> constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setI16Const(i16Const >> constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setI16Const(i16Const >> constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setU16Const(u16Const >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU16Const(u16Const >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setU16Const(u16Const >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const >> constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setU16Const(u16Const >> constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setU16Const(u16Const >> constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setU16Const(u16Const >> constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setU16Const(u16Const >> constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
||||||
case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break;
|
case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break;
|
case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break;
|
||||||
|
@ -362,6 +585,10 @@ public:
|
||||||
break;
|
break;
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break;
|
case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break;
|
case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break;
|
||||||
|
@ -371,6 +598,10 @@ public:
|
||||||
break;
|
break;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setI64Const(i64Const >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI64Const(i64Const >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setI64Const(i64Const >> constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setI64Const(i64Const >> constant.iConst); break;
|
case EbtInt: returnValue.setI64Const(i64Const >> constant.iConst); break;
|
||||||
case EbtUint: returnValue.setI64Const(i64Const >> constant.uConst); break;
|
case EbtUint: returnValue.setI64Const(i64Const >> constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const >> constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const >> constant.i64Const); break;
|
||||||
|
@ -380,6 +611,10 @@ public:
|
||||||
break;
|
break;
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setU64Const(u64Const >> constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU64Const(u64Const >> constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setU64Const(u64Const >> constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU64Const(u64Const >> constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setU64Const(u64Const >> constant.iConst); break;
|
case EbtInt: returnValue.setU64Const(u64Const >> constant.iConst); break;
|
||||||
case EbtUint: returnValue.setU64Const(u64Const >> constant.uConst); break;
|
case EbtUint: returnValue.setU64Const(u64Const >> constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setU64Const(u64Const >> constant.i64Const); break;
|
case EbtInt64: returnValue.setU64Const(u64Const >> constant.i64Const); break;
|
||||||
|
@ -397,8 +632,64 @@ public:
|
||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setI8Const(i8Const << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI8Const(i8Const << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setI8Const(i8Const << constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setI8Const(i8Const << constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setI8Const(i8Const << constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setI8Const(i8Const << constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setI8Const(i8Const << constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint8:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setU8Const(u8Const << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setU8Const(u8Const << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU8Const(u8Const << constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setU8Const(u8Const << constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setU8Const(u8Const << constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setU8Const(u8Const << constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setU8Const(u8Const << constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtInt16:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setI16Const(i16Const << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setI16Const(i16Const << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setI16Const(i16Const << constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setI16Const(i16Const << constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setI16Const(i16Const << constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setI16Const(i16Const << constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setI16Const(i16Const << constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setU16Const(u16Const << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU16Const(u16Const << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setU16Const(u16Const << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const << constant.u16Const); break;
|
||||||
|
case EbtInt: returnValue.setU16Const(u16Const << constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setU16Const(u16Const << constant.uConst); break;
|
||||||
|
case EbtInt64: returnValue.setU16Const(u16Const << constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setU16Const(u16Const << constant.u64Const); break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||||
case EbtUint: returnValue.setIConst(iConst << constant.uConst); break;
|
case EbtUint: returnValue.setIConst(iConst << constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break;
|
case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break;
|
||||||
|
@ -408,6 +699,10 @@ public:
|
||||||
break;
|
break;
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setUConst(uConst << constant.iConst); break;
|
case EbtInt: returnValue.setUConst(uConst << constant.iConst); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break;
|
case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break;
|
||||||
|
@ -417,6 +712,10 @@ public:
|
||||||
break;
|
break;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setI64Const(i64Const << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI64Const(i64Const << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setI64Const(i64Const << constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setI64Const(i64Const << constant.iConst); break;
|
case EbtInt: returnValue.setI64Const(i64Const << constant.iConst); break;
|
||||||
case EbtUint: returnValue.setI64Const(i64Const << constant.uConst); break;
|
case EbtUint: returnValue.setI64Const(i64Const << constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const << constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const << constant.i64Const); break;
|
||||||
|
@ -426,6 +725,10 @@ public:
|
||||||
break;
|
break;
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt8: returnValue.setU64Const(u64Const << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU64Const(u64Const << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setU64Const(u64Const << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU64Const(u64Const << constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setU64Const(u64Const << constant.iConst); break;
|
case EbtInt: returnValue.setU64Const(u64Const << constant.iConst); break;
|
||||||
case EbtUint: returnValue.setU64Const(u64Const << constant.uConst); break;
|
case EbtUint: returnValue.setU64Const(u64Const << constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setU64Const(u64Const << constant.i64Const); break;
|
case EbtInt64: returnValue.setU64Const(u64Const << constant.i64Const); break;
|
||||||
|
@ -444,6 +747,10 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break;
|
||||||
|
@ -459,6 +766,10 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break;
|
||||||
|
@ -474,6 +785,10 @@ public:
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
|
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
|
case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break;
|
||||||
|
@ -488,6 +803,10 @@ public:
|
||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt8: returnValue.setI8Const(~i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setU8Const(~u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setI16Const(~i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setU16Const(~u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(~iConst); break;
|
case EbtInt: returnValue.setIConst(~iConst); break;
|
||||||
case EbtUint: returnValue.setUConst(~uConst); break;
|
case EbtUint: returnValue.setUConst(~uConst); break;
|
||||||
case EbtInt64: returnValue.setI64Const(~i64Const); break;
|
case EbtInt64: returnValue.setI64Const(~i64Const); break;
|
||||||
|
@ -526,19 +845,24 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
union {
|
||||||
|
signed char i8Const; // used for i8vec, scalar int8s
|
||||||
|
unsigned char u8Const; // used for u8vec, scalar uint8s
|
||||||
|
signed short i16Const; // used for i16vec, scalar int16s
|
||||||
|
unsigned short u16Const; // used for u16vec, scalar uint16s
|
||||||
int iConst; // used for ivec, scalar ints
|
int iConst; // used for ivec, scalar ints
|
||||||
unsigned int uConst; // used for uvec, scalar uints
|
unsigned int uConst; // used for uvec, scalar uints
|
||||||
long long i64Const; // used for i64vec, scalar int64s
|
long long i64Const; // used for i64vec, scalar int64s
|
||||||
unsigned long long u64Const; // used for u64vec, scalar uint64s
|
unsigned long long u64Const; // used for u64vec, scalar uint64s
|
||||||
bool bConst; // used for bvec, scalar bools
|
bool bConst; // used for bvec, scalar bools
|
||||||
double dConst; // used for vec, dvec, mat, dmat, scalar floats and doubles
|
double dConst; // used for vec, dvec, mat, dmat, scalar floats and doubles
|
||||||
|
const TString* sConst; // string constant
|
||||||
};
|
};
|
||||||
|
|
||||||
TBasicType type;
|
TBasicType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Encapsulate having a pointer to an array of TConstUnion,
|
// Encapsulate having a pointer to an array of TConstUnion,
|
||||||
// which only needs to be allocated if it's size is going to be
|
// which only needs to be allocated if its size is going to be
|
||||||
// bigger than 0.
|
// bigger than 0.
|
||||||
//
|
//
|
||||||
// One convenience is being able to use [] to go inside the array, instead
|
// One convenience is being able to use [] to go inside the array, instead
|
||||||
|
@ -587,9 +911,6 @@ public:
|
||||||
if (! unionArray || ! rhs.unionArray)
|
if (! unionArray || ! rhs.unionArray)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (! unionArray || ! rhs.unionArray)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return *unionArray == *rhs.unionArray;
|
return *unionArray == *rhs.unionArray;
|
||||||
}
|
}
|
||||||
bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); }
|
bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); }
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,25 +18,25 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _INFOSINK_INCLUDED_
|
#ifndef _INFOSINK_INCLUDED_
|
||||||
#define _INFOSINK_INCLUDED_
|
#define _INFOSINK_INCLUDED_
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ public:
|
||||||
TInfoSinkBase& operator<<(const char* s) { append(s); return *this; }
|
TInfoSinkBase& operator<<(const char* s) { append(s); return *this; }
|
||||||
TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; }
|
TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; }
|
||||||
TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; }
|
TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; }
|
||||||
TInfoSinkBase& operator<<(long unsigned int n) { append(String(n)); return *this; }
|
|
||||||
TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size];
|
TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size];
|
||||||
snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n);
|
snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n);
|
||||||
append(buf);
|
append(buf);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
|
#ifndef __INITIALIZE_GLOBALS_INCLUDED_
|
||||||
|
@ -37,10 +37,7 @@
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
void InitializeMemoryPools();
|
|
||||||
void FreeGlobalPools();
|
|
||||||
bool InitializePoolIndex();
|
bool InitializePoolIndex();
|
||||||
void FreePoolIndex();
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _POOLALLOC_INCLUDED_
|
#ifndef _POOLALLOC_INCLUDED_
|
||||||
|
@ -61,13 +61,13 @@
|
||||||
// class as the allocator (second) template argument.
|
// class as the allocator (second) template argument.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <cstddef>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
// If we are using guard blocks, we must track each indivual
|
// If we are using guard blocks, we must track each individual
|
||||||
// allocation. If we aren't using guard blocks, these
|
// allocation. If we aren't using guard blocks, these
|
||||||
// never get instantiated, so won't have any impact.
|
// never get instantiated, so won't have any impact.
|
||||||
//
|
//
|
||||||
|
@ -245,21 +245,13 @@ private:
|
||||||
TPoolAllocator(const TPoolAllocator&); // don't allow default copy constructor
|
TPoolAllocator(const TPoolAllocator&); // don't allow default copy constructor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// There could potentially be many pools with pops happening at
|
// There could potentially be many pools with pops happening at
|
||||||
// different times. But a simple use is to have a global pop
|
// different times. But a simple use is to have a global pop
|
||||||
// with everyone using the same global allocator.
|
// with everyone using the same global allocator.
|
||||||
//
|
//
|
||||||
typedef TPoolAllocator* PoolAllocatorPointer;
|
|
||||||
extern TPoolAllocator& GetThreadPoolAllocator();
|
extern TPoolAllocator& GetThreadPoolAllocator();
|
||||||
|
void SetThreadPoolAllocator(TPoolAllocator* poolAllocator);
|
||||||
struct TThreadMemoryPools
|
|
||||||
{
|
|
||||||
TPoolAllocator* threadPoolAllocator;
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetThreadPoolAllocator(TPoolAllocator& poolAllocator);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// This STL compatible allocator is intended to be used as the allocator
|
// This STL compatible allocator is intended to be used as the allocator
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _RESOURCE_LIMITS_INCLUDED_
|
#ifndef _RESOURCE_LIMITS_INCLUDED_
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _SHHANDLE_INCLUDED_
|
#ifndef _SHHANDLE_INCLUDED_
|
||||||
|
@ -42,7 +42,6 @@
|
||||||
// This should not be included by driver code.
|
// This should not be included by driver code.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#define SH_EXPORTING
|
#define SH_EXPORTING
|
||||||
#include "../Public/ShaderLang.h"
|
#include "../Public/ShaderLang.h"
|
||||||
#include "../MachineIndependent/Versions.h"
|
#include "../MachineIndependent/Versions.h"
|
||||||
|
@ -57,11 +56,14 @@ class TUniformMap;
|
||||||
//
|
//
|
||||||
class TShHandleBase {
|
class TShHandleBase {
|
||||||
public:
|
public:
|
||||||
TShHandleBase() { }
|
TShHandleBase() { pool = new glslang::TPoolAllocator; }
|
||||||
virtual ~TShHandleBase() { }
|
virtual ~TShHandleBase() { delete pool; }
|
||||||
virtual TCompiler* getAsCompiler() { return 0; }
|
virtual TCompiler* getAsCompiler() { return 0; }
|
||||||
virtual TLinker* getAsLinker() { return 0; }
|
virtual TLinker* getAsLinker() { return 0; }
|
||||||
virtual TUniformMap* getAsUniformMap() { return 0; }
|
virtual TUniformMap* getAsUniformMap() { return 0; }
|
||||||
|
virtual glslang::TPoolAllocator* getPool() const { return pool; }
|
||||||
|
private:
|
||||||
|
glslang::TPoolAllocator* pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -41,6 +41,8 @@
|
||||||
#ifndef _ARRAYS_INCLUDED
|
#ifndef _ARRAYS_INCLUDED
|
||||||
#define _ARRAYS_INCLUDED
|
#define _ARRAYS_INCLUDED
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
// This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else.
|
// This is used to mean there is no size yet (unsized), it is waiting to get a size from somewhere else.
|
||||||
|
@ -130,10 +132,10 @@ struct TSmallArrayVector {
|
||||||
sizes->push_back(pair);
|
sizes->push_back(pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
void push_front(const TSmallArrayVector& newDims)
|
void push_back(const TSmallArrayVector& newDims)
|
||||||
{
|
{
|
||||||
alloc();
|
alloc();
|
||||||
sizes->insert(sizes->begin(), newDims.sizes->begin(), newDims.sizes->end());
|
sizes->insert(sizes->end(), newDims.sizes->begin(), newDims.sizes->end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_front()
|
void pop_front()
|
||||||
|
@ -220,12 +222,13 @@ protected:
|
||||||
struct TArraySizes {
|
struct TArraySizes {
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
|
|
||||||
TArraySizes() : implicitArraySize(1) { }
|
TArraySizes() : implicitArraySize(1), variablyIndexed(false) { }
|
||||||
|
|
||||||
// For breaking into two non-shared copies, independently modifiable.
|
// For breaking into two non-shared copies, independently modifiable.
|
||||||
TArraySizes& operator=(const TArraySizes& from)
|
TArraySizes& operator=(const TArraySizes& from)
|
||||||
{
|
{
|
||||||
implicitArraySize = from.implicitArraySize;
|
implicitArraySize = from.implicitArraySize;
|
||||||
|
variablyIndexed = from.variablyIndexed;
|
||||||
sizes = from.sizes;
|
sizes = from.sizes;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -252,10 +255,11 @@ struct TArraySizes {
|
||||||
void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); }
|
void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); }
|
||||||
void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); }
|
void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); }
|
||||||
void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); }
|
void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); }
|
||||||
|
void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); }
|
||||||
void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
|
void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
|
||||||
int getImplicitSize() const { return (int)implicitArraySize; }
|
int getImplicitSize() const { return implicitArraySize; }
|
||||||
void setImplicitSize(int s) { implicitArraySize = s; }
|
void updateImplicitSize(int s) { implicitArraySize = std::max(implicitArraySize, s); }
|
||||||
bool isInnerImplicit() const
|
bool isInnerUnsized() const
|
||||||
{
|
{
|
||||||
for (int d = 1; d < sizes.size(); ++d) {
|
for (int d = 1; d < sizes.size(); ++d) {
|
||||||
if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize)
|
if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize)
|
||||||
|
@ -264,8 +268,31 @@ struct TArraySizes {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
|
bool clearInnerUnsized()
|
||||||
void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
|
{
|
||||||
|
for (int d = 1; d < sizes.size(); ++d) {
|
||||||
|
if (sizes.getDimSize(d) == (unsigned)UnsizedArraySize)
|
||||||
|
setDimSize(d, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool isInnerSpecialization() const
|
||||||
|
{
|
||||||
|
for (int d = 1; d < sizes.size(); ++d) {
|
||||||
|
if (sizes.getDimNode(d) != nullptr)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool isOuterSpecialization()
|
||||||
|
{
|
||||||
|
return sizes.getDimNode(0) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasUnsized() const { return getOuterSize() == UnsizedArraySize || isInnerUnsized(); }
|
||||||
|
bool isSized() const { return getOuterSize() != UnsizedArraySize; }
|
||||||
void dereference() { sizes.pop_front(); }
|
void dereference() { sizes.pop_front(); }
|
||||||
void copyDereferenced(const TArraySizes& rhs)
|
void copyDereferenced(const TArraySizes& rhs)
|
||||||
{
|
{
|
||||||
|
@ -288,17 +315,8 @@ struct TArraySizes {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if any of the dimensions of the array is sized with a node
|
void setVariablyIndexed() { variablyIndexed = true; }
|
||||||
// instead of a front-end compile-time constant.
|
bool isVariablyIndexed() const { return variablyIndexed; }
|
||||||
bool containsNode()
|
|
||||||
{
|
|
||||||
for (int d = 0; d < sizes.size(); ++d) {
|
|
||||||
if (sizes.getDimNode(d) != nullptr)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
|
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
|
||||||
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
|
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
|
||||||
|
@ -308,9 +326,12 @@ protected:
|
||||||
|
|
||||||
TArraySizes(const TArraySizes&);
|
TArraySizes(const TArraySizes&);
|
||||||
|
|
||||||
// for tracking maximum referenced index, before an explicit size is given
|
// For tracking maximum referenced compile-time constant index.
|
||||||
// applies only to the outer-most dimension
|
// Applies only to the outer-most dimension. Potentially becomes
|
||||||
|
// the implicit size of the array, if not variably indexed and
|
||||||
|
// otherwise legal.
|
||||||
int implicitArraySize;
|
int implicitArraySize;
|
||||||
|
bool variablyIndexed; // true if array is indexed with a non compile-time constant
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +21,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -46,12 +47,19 @@
|
||||||
#ifndef __INTERMEDIATE_H
|
#ifndef __INTERMEDIATE_H
|
||||||
#define __INTERMEDIATE_H
|
#define __INTERMEDIATE_H
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
|
#pragma warning(disable : 4464) // relative include path contains '..'
|
||||||
|
#pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
#include "../Include/Types.h"
|
#include "../Include/Types.h"
|
||||||
#include "../Include/ConstantUnion.h"
|
#include "../Include/ConstantUnion.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
class TIntermediate;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Operators used by the high-level (parse tree) representation.
|
// Operators used by the high-level (parse tree) representation.
|
||||||
//
|
//
|
||||||
|
@ -77,49 +85,190 @@ enum TOperator {
|
||||||
EOpPreIncrement,
|
EOpPreIncrement,
|
||||||
EOpPreDecrement,
|
EOpPreDecrement,
|
||||||
|
|
||||||
|
// (u)int* -> bool
|
||||||
|
EOpConvInt8ToBool,
|
||||||
|
EOpConvUint8ToBool,
|
||||||
|
EOpConvInt16ToBool,
|
||||||
|
EOpConvUint16ToBool,
|
||||||
EOpConvIntToBool,
|
EOpConvIntToBool,
|
||||||
EOpConvUintToBool,
|
EOpConvUintToBool,
|
||||||
EOpConvFloatToBool,
|
|
||||||
EOpConvDoubleToBool,
|
|
||||||
EOpConvInt64ToBool,
|
EOpConvInt64ToBool,
|
||||||
EOpConvUint64ToBool,
|
EOpConvUint64ToBool,
|
||||||
EOpConvBoolToFloat,
|
|
||||||
EOpConvIntToFloat,
|
// float* -> bool
|
||||||
EOpConvUintToFloat,
|
EOpConvFloat16ToBool,
|
||||||
EOpConvDoubleToFloat,
|
EOpConvFloatToBool,
|
||||||
EOpConvInt64ToFloat,
|
EOpConvDoubleToBool,
|
||||||
EOpConvUint64ToFloat,
|
|
||||||
EOpConvUintToInt,
|
// bool -> (u)int*
|
||||||
EOpConvFloatToInt,
|
EOpConvBoolToInt8,
|
||||||
|
EOpConvBoolToUint8,
|
||||||
|
EOpConvBoolToInt16,
|
||||||
|
EOpConvBoolToUint16,
|
||||||
EOpConvBoolToInt,
|
EOpConvBoolToInt,
|
||||||
EOpConvDoubleToInt,
|
|
||||||
EOpConvInt64ToInt,
|
|
||||||
EOpConvUint64ToInt,
|
|
||||||
EOpConvIntToUint,
|
|
||||||
EOpConvFloatToUint,
|
|
||||||
EOpConvBoolToUint,
|
EOpConvBoolToUint,
|
||||||
EOpConvDoubleToUint,
|
|
||||||
EOpConvInt64ToUint,
|
|
||||||
EOpConvUint64ToUint,
|
|
||||||
EOpConvIntToDouble,
|
|
||||||
EOpConvUintToDouble,
|
|
||||||
EOpConvFloatToDouble,
|
|
||||||
EOpConvBoolToDouble,
|
|
||||||
EOpConvInt64ToDouble,
|
|
||||||
EOpConvUint64ToDouble,
|
|
||||||
EOpConvBoolToInt64,
|
EOpConvBoolToInt64,
|
||||||
EOpConvIntToInt64,
|
|
||||||
EOpConvUintToInt64,
|
|
||||||
EOpConvFloatToInt64,
|
|
||||||
EOpConvDoubleToInt64,
|
|
||||||
EOpConvUint64ToInt64,
|
|
||||||
EOpConvBoolToUint64,
|
EOpConvBoolToUint64,
|
||||||
|
|
||||||
|
// bool -> float*
|
||||||
|
EOpConvBoolToFloat16,
|
||||||
|
EOpConvBoolToFloat,
|
||||||
|
EOpConvBoolToDouble,
|
||||||
|
|
||||||
|
// int8_t -> (u)int*
|
||||||
|
EOpConvInt8ToInt16,
|
||||||
|
EOpConvInt8ToInt,
|
||||||
|
EOpConvInt8ToInt64,
|
||||||
|
EOpConvInt8ToUint8,
|
||||||
|
EOpConvInt8ToUint16,
|
||||||
|
EOpConvInt8ToUint,
|
||||||
|
EOpConvInt8ToUint64,
|
||||||
|
|
||||||
|
// uint8_t -> (u)int*
|
||||||
|
EOpConvUint8ToInt8,
|
||||||
|
EOpConvUint8ToInt16,
|
||||||
|
EOpConvUint8ToInt,
|
||||||
|
EOpConvUint8ToInt64,
|
||||||
|
EOpConvUint8ToUint16,
|
||||||
|
EOpConvUint8ToUint,
|
||||||
|
EOpConvUint8ToUint64,
|
||||||
|
|
||||||
|
// int8_t -> float*
|
||||||
|
EOpConvInt8ToFloat16,
|
||||||
|
EOpConvInt8ToFloat,
|
||||||
|
EOpConvInt8ToDouble,
|
||||||
|
|
||||||
|
// uint8_t -> float*
|
||||||
|
EOpConvUint8ToFloat16,
|
||||||
|
EOpConvUint8ToFloat,
|
||||||
|
EOpConvUint8ToDouble,
|
||||||
|
|
||||||
|
// int16_t -> (u)int*
|
||||||
|
EOpConvInt16ToInt8,
|
||||||
|
EOpConvInt16ToInt,
|
||||||
|
EOpConvInt16ToInt64,
|
||||||
|
EOpConvInt16ToUint8,
|
||||||
|
EOpConvInt16ToUint16,
|
||||||
|
EOpConvInt16ToUint,
|
||||||
|
EOpConvInt16ToUint64,
|
||||||
|
|
||||||
|
// uint16_t -> (u)int*
|
||||||
|
EOpConvUint16ToInt8,
|
||||||
|
EOpConvUint16ToInt16,
|
||||||
|
EOpConvUint16ToInt,
|
||||||
|
EOpConvUint16ToInt64,
|
||||||
|
EOpConvUint16ToUint8,
|
||||||
|
EOpConvUint16ToUint,
|
||||||
|
EOpConvUint16ToUint64,
|
||||||
|
|
||||||
|
// int16_t -> float*
|
||||||
|
EOpConvInt16ToFloat16,
|
||||||
|
EOpConvInt16ToFloat,
|
||||||
|
EOpConvInt16ToDouble,
|
||||||
|
|
||||||
|
// uint16_t -> float*
|
||||||
|
EOpConvUint16ToFloat16,
|
||||||
|
EOpConvUint16ToFloat,
|
||||||
|
EOpConvUint16ToDouble,
|
||||||
|
|
||||||
|
// int32_t -> (u)int*
|
||||||
|
EOpConvIntToInt8,
|
||||||
|
EOpConvIntToInt16,
|
||||||
|
EOpConvIntToInt64,
|
||||||
|
EOpConvIntToUint8,
|
||||||
|
EOpConvIntToUint16,
|
||||||
|
EOpConvIntToUint,
|
||||||
EOpConvIntToUint64,
|
EOpConvIntToUint64,
|
||||||
|
|
||||||
|
// uint32_t -> (u)int*
|
||||||
|
EOpConvUintToInt8,
|
||||||
|
EOpConvUintToInt16,
|
||||||
|
EOpConvUintToInt,
|
||||||
|
EOpConvUintToInt64,
|
||||||
|
EOpConvUintToUint8,
|
||||||
|
EOpConvUintToUint16,
|
||||||
EOpConvUintToUint64,
|
EOpConvUintToUint64,
|
||||||
EOpConvFloatToUint64,
|
|
||||||
EOpConvDoubleToUint64,
|
// int32_t -> float*
|
||||||
|
EOpConvIntToFloat16,
|
||||||
|
EOpConvIntToFloat,
|
||||||
|
EOpConvIntToDouble,
|
||||||
|
|
||||||
|
// uint32_t -> float*
|
||||||
|
EOpConvUintToFloat16,
|
||||||
|
EOpConvUintToFloat,
|
||||||
|
EOpConvUintToDouble,
|
||||||
|
|
||||||
|
// int64_t -> (u)int*
|
||||||
|
EOpConvInt64ToInt8,
|
||||||
|
EOpConvInt64ToInt16,
|
||||||
|
EOpConvInt64ToInt,
|
||||||
|
EOpConvInt64ToUint8,
|
||||||
|
EOpConvInt64ToUint16,
|
||||||
|
EOpConvInt64ToUint,
|
||||||
EOpConvInt64ToUint64,
|
EOpConvInt64ToUint64,
|
||||||
|
|
||||||
|
// uint64_t -> (u)int*
|
||||||
|
EOpConvUint64ToInt8,
|
||||||
|
EOpConvUint64ToInt16,
|
||||||
|
EOpConvUint64ToInt,
|
||||||
|
EOpConvUint64ToInt64,
|
||||||
|
EOpConvUint64ToUint8,
|
||||||
|
EOpConvUint64ToUint16,
|
||||||
|
EOpConvUint64ToUint,
|
||||||
|
|
||||||
|
// int64_t -> float*
|
||||||
|
EOpConvInt64ToFloat16,
|
||||||
|
EOpConvInt64ToFloat,
|
||||||
|
EOpConvInt64ToDouble,
|
||||||
|
|
||||||
|
// uint64_t -> float*
|
||||||
|
EOpConvUint64ToFloat16,
|
||||||
|
EOpConvUint64ToFloat,
|
||||||
|
EOpConvUint64ToDouble,
|
||||||
|
|
||||||
|
// float16_t -> (u)int*
|
||||||
|
EOpConvFloat16ToInt8,
|
||||||
|
EOpConvFloat16ToInt16,
|
||||||
|
EOpConvFloat16ToInt,
|
||||||
|
EOpConvFloat16ToInt64,
|
||||||
|
EOpConvFloat16ToUint8,
|
||||||
|
EOpConvFloat16ToUint16,
|
||||||
|
EOpConvFloat16ToUint,
|
||||||
|
EOpConvFloat16ToUint64,
|
||||||
|
|
||||||
|
// float16_t -> float*
|
||||||
|
EOpConvFloat16ToFloat,
|
||||||
|
EOpConvFloat16ToDouble,
|
||||||
|
|
||||||
|
// float -> (u)int*
|
||||||
|
EOpConvFloatToInt8,
|
||||||
|
EOpConvFloatToInt16,
|
||||||
|
EOpConvFloatToInt,
|
||||||
|
EOpConvFloatToInt64,
|
||||||
|
EOpConvFloatToUint8,
|
||||||
|
EOpConvFloatToUint16,
|
||||||
|
EOpConvFloatToUint,
|
||||||
|
EOpConvFloatToUint64,
|
||||||
|
|
||||||
|
// float -> float*
|
||||||
|
EOpConvFloatToFloat16,
|
||||||
|
EOpConvFloatToDouble,
|
||||||
|
|
||||||
|
// float64 _t-> (u)int*
|
||||||
|
EOpConvDoubleToInt8,
|
||||||
|
EOpConvDoubleToInt16,
|
||||||
|
EOpConvDoubleToInt,
|
||||||
|
EOpConvDoubleToInt64,
|
||||||
|
EOpConvDoubleToUint8,
|
||||||
|
EOpConvDoubleToUint16,
|
||||||
|
EOpConvDoubleToUint,
|
||||||
|
EOpConvDoubleToUint64,
|
||||||
|
|
||||||
|
// float64_t -> float*
|
||||||
|
EOpConvDoubleToFloat16,
|
||||||
|
EOpConvDoubleToFloat,
|
||||||
|
|
||||||
//
|
//
|
||||||
// binary operations
|
// binary operations
|
||||||
//
|
//
|
||||||
|
@ -160,6 +309,7 @@ enum TOperator {
|
||||||
EOpVectorSwizzle,
|
EOpVectorSwizzle,
|
||||||
|
|
||||||
EOpMethod,
|
EOpMethod,
|
||||||
|
EOpScoping,
|
||||||
|
|
||||||
//
|
//
|
||||||
// Built-in functions mapped to operators
|
// Built-in functions mapped to operators
|
||||||
|
@ -220,6 +370,10 @@ enum TOperator {
|
||||||
EOpDoubleBitsToUint64,
|
EOpDoubleBitsToUint64,
|
||||||
EOpInt64BitsToDouble,
|
EOpInt64BitsToDouble,
|
||||||
EOpUint64BitsToDouble,
|
EOpUint64BitsToDouble,
|
||||||
|
EOpFloat16BitsToInt16,
|
||||||
|
EOpFloat16BitsToUint16,
|
||||||
|
EOpInt16BitsToFloat16,
|
||||||
|
EOpUint16BitsToFloat16,
|
||||||
EOpPackSnorm2x16,
|
EOpPackSnorm2x16,
|
||||||
EOpUnpackSnorm2x16,
|
EOpUnpackSnorm2x16,
|
||||||
EOpPackUnorm2x16,
|
EOpPackUnorm2x16,
|
||||||
|
@ -236,6 +390,22 @@ enum TOperator {
|
||||||
EOpUnpackInt2x32,
|
EOpUnpackInt2x32,
|
||||||
EOpPackUint2x32,
|
EOpPackUint2x32,
|
||||||
EOpUnpackUint2x32,
|
EOpUnpackUint2x32,
|
||||||
|
EOpPackFloat2x16,
|
||||||
|
EOpUnpackFloat2x16,
|
||||||
|
EOpPackInt2x16,
|
||||||
|
EOpUnpackInt2x16,
|
||||||
|
EOpPackUint2x16,
|
||||||
|
EOpUnpackUint2x16,
|
||||||
|
EOpPackInt4x16,
|
||||||
|
EOpUnpackInt4x16,
|
||||||
|
EOpPackUint4x16,
|
||||||
|
EOpUnpackUint4x16,
|
||||||
|
EOpPack16,
|
||||||
|
EOpPack32,
|
||||||
|
EOpPack64,
|
||||||
|
EOpUnpack32,
|
||||||
|
EOpUnpack16,
|
||||||
|
EOpUnpack8,
|
||||||
|
|
||||||
EOpLength,
|
EOpLength,
|
||||||
EOpDistance,
|
EOpDistance,
|
||||||
|
@ -246,6 +416,12 @@ enum TOperator {
|
||||||
EOpReflect,
|
EOpReflect,
|
||||||
EOpRefract,
|
EOpRefract,
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpMin3,
|
||||||
|
EOpMax3,
|
||||||
|
EOpMid3,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpDPdx, // Fragment only
|
EOpDPdx, // Fragment only
|
||||||
EOpDPdy, // Fragment only
|
EOpDPdy, // Fragment only
|
||||||
EOpFwidth, // Fragment only
|
EOpFwidth, // Fragment only
|
||||||
|
@ -260,6 +436,10 @@ enum TOperator {
|
||||||
EOpInterpolateAtSample, // Fragment only
|
EOpInterpolateAtSample, // Fragment only
|
||||||
EOpInterpolateAtOffset, // Fragment only
|
EOpInterpolateAtOffset, // Fragment only
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpInterpolateAtVertex,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpMatrixTimesMatrix,
|
EOpMatrixTimesMatrix,
|
||||||
EOpOuterProduct,
|
EOpOuterProduct,
|
||||||
EOpDeterminant,
|
EOpDeterminant,
|
||||||
|
@ -291,6 +471,119 @@ enum TOperator {
|
||||||
EOpAllInvocations,
|
EOpAllInvocations,
|
||||||
EOpAllInvocationsEqual,
|
EOpAllInvocationsEqual,
|
||||||
|
|
||||||
|
EOpSubgroupGuardStart,
|
||||||
|
EOpSubgroupBarrier,
|
||||||
|
EOpSubgroupMemoryBarrier,
|
||||||
|
EOpSubgroupMemoryBarrierBuffer,
|
||||||
|
EOpSubgroupMemoryBarrierImage,
|
||||||
|
EOpSubgroupMemoryBarrierShared, // compute only
|
||||||
|
EOpSubgroupElect,
|
||||||
|
EOpSubgroupAll,
|
||||||
|
EOpSubgroupAny,
|
||||||
|
EOpSubgroupAllEqual,
|
||||||
|
EOpSubgroupBroadcast,
|
||||||
|
EOpSubgroupBroadcastFirst,
|
||||||
|
EOpSubgroupBallot,
|
||||||
|
EOpSubgroupInverseBallot,
|
||||||
|
EOpSubgroupBallotBitExtract,
|
||||||
|
EOpSubgroupBallotBitCount,
|
||||||
|
EOpSubgroupBallotInclusiveBitCount,
|
||||||
|
EOpSubgroupBallotExclusiveBitCount,
|
||||||
|
EOpSubgroupBallotFindLSB,
|
||||||
|
EOpSubgroupBallotFindMSB,
|
||||||
|
EOpSubgroupShuffle,
|
||||||
|
EOpSubgroupShuffleXor,
|
||||||
|
EOpSubgroupShuffleUp,
|
||||||
|
EOpSubgroupShuffleDown,
|
||||||
|
EOpSubgroupAdd,
|
||||||
|
EOpSubgroupMul,
|
||||||
|
EOpSubgroupMin,
|
||||||
|
EOpSubgroupMax,
|
||||||
|
EOpSubgroupAnd,
|
||||||
|
EOpSubgroupOr,
|
||||||
|
EOpSubgroupXor,
|
||||||
|
EOpSubgroupInclusiveAdd,
|
||||||
|
EOpSubgroupInclusiveMul,
|
||||||
|
EOpSubgroupInclusiveMin,
|
||||||
|
EOpSubgroupInclusiveMax,
|
||||||
|
EOpSubgroupInclusiveAnd,
|
||||||
|
EOpSubgroupInclusiveOr,
|
||||||
|
EOpSubgroupInclusiveXor,
|
||||||
|
EOpSubgroupExclusiveAdd,
|
||||||
|
EOpSubgroupExclusiveMul,
|
||||||
|
EOpSubgroupExclusiveMin,
|
||||||
|
EOpSubgroupExclusiveMax,
|
||||||
|
EOpSubgroupExclusiveAnd,
|
||||||
|
EOpSubgroupExclusiveOr,
|
||||||
|
EOpSubgroupExclusiveXor,
|
||||||
|
EOpSubgroupClusteredAdd,
|
||||||
|
EOpSubgroupClusteredMul,
|
||||||
|
EOpSubgroupClusteredMin,
|
||||||
|
EOpSubgroupClusteredMax,
|
||||||
|
EOpSubgroupClusteredAnd,
|
||||||
|
EOpSubgroupClusteredOr,
|
||||||
|
EOpSubgroupClusteredXor,
|
||||||
|
EOpSubgroupQuadBroadcast,
|
||||||
|
EOpSubgroupQuadSwapHorizontal,
|
||||||
|
EOpSubgroupQuadSwapVertical,
|
||||||
|
EOpSubgroupQuadSwapDiagonal,
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
EOpSubgroupPartition,
|
||||||
|
EOpSubgroupPartitionedAdd,
|
||||||
|
EOpSubgroupPartitionedMul,
|
||||||
|
EOpSubgroupPartitionedMin,
|
||||||
|
EOpSubgroupPartitionedMax,
|
||||||
|
EOpSubgroupPartitionedAnd,
|
||||||
|
EOpSubgroupPartitionedOr,
|
||||||
|
EOpSubgroupPartitionedXor,
|
||||||
|
EOpSubgroupPartitionedInclusiveAdd,
|
||||||
|
EOpSubgroupPartitionedInclusiveMul,
|
||||||
|
EOpSubgroupPartitionedInclusiveMin,
|
||||||
|
EOpSubgroupPartitionedInclusiveMax,
|
||||||
|
EOpSubgroupPartitionedInclusiveAnd,
|
||||||
|
EOpSubgroupPartitionedInclusiveOr,
|
||||||
|
EOpSubgroupPartitionedInclusiveXor,
|
||||||
|
EOpSubgroupPartitionedExclusiveAdd,
|
||||||
|
EOpSubgroupPartitionedExclusiveMul,
|
||||||
|
EOpSubgroupPartitionedExclusiveMin,
|
||||||
|
EOpSubgroupPartitionedExclusiveMax,
|
||||||
|
EOpSubgroupPartitionedExclusiveAnd,
|
||||||
|
EOpSubgroupPartitionedExclusiveOr,
|
||||||
|
EOpSubgroupPartitionedExclusiveXor,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EOpSubgroupGuardStop,
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpMinInvocations,
|
||||||
|
EOpMaxInvocations,
|
||||||
|
EOpAddInvocations,
|
||||||
|
EOpMinInvocationsNonUniform,
|
||||||
|
EOpMaxInvocationsNonUniform,
|
||||||
|
EOpAddInvocationsNonUniform,
|
||||||
|
EOpMinInvocationsInclusiveScan,
|
||||||
|
EOpMaxInvocationsInclusiveScan,
|
||||||
|
EOpAddInvocationsInclusiveScan,
|
||||||
|
EOpMinInvocationsInclusiveScanNonUniform,
|
||||||
|
EOpMaxInvocationsInclusiveScanNonUniform,
|
||||||
|
EOpAddInvocationsInclusiveScanNonUniform,
|
||||||
|
EOpMinInvocationsExclusiveScan,
|
||||||
|
EOpMaxInvocationsExclusiveScan,
|
||||||
|
EOpAddInvocationsExclusiveScan,
|
||||||
|
EOpMinInvocationsExclusiveScanNonUniform,
|
||||||
|
EOpMaxInvocationsExclusiveScanNonUniform,
|
||||||
|
EOpAddInvocationsExclusiveScanNonUniform,
|
||||||
|
EOpSwizzleInvocations,
|
||||||
|
EOpSwizzleInvocationsMasked,
|
||||||
|
EOpWriteInvocation,
|
||||||
|
EOpMbcnt,
|
||||||
|
|
||||||
|
EOpCubeFaceIndex,
|
||||||
|
EOpCubeFaceCoord,
|
||||||
|
EOpTime,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpAtomicAdd,
|
EOpAtomicAdd,
|
||||||
EOpAtomicMin,
|
EOpAtomicMin,
|
||||||
EOpAtomicMax,
|
EOpAtomicMax,
|
||||||
|
@ -300,9 +593,18 @@ enum TOperator {
|
||||||
EOpAtomicExchange,
|
EOpAtomicExchange,
|
||||||
EOpAtomicCompSwap,
|
EOpAtomicCompSwap,
|
||||||
|
|
||||||
EOpAtomicCounterIncrement,
|
EOpAtomicCounterIncrement, // results in pre-increment value
|
||||||
EOpAtomicCounterDecrement,
|
EOpAtomicCounterDecrement, // results in post-decrement value
|
||||||
EOpAtomicCounter,
|
EOpAtomicCounter,
|
||||||
|
EOpAtomicCounterAdd,
|
||||||
|
EOpAtomicCounterSubtract,
|
||||||
|
EOpAtomicCounterMin,
|
||||||
|
EOpAtomicCounterMax,
|
||||||
|
EOpAtomicCounterAnd,
|
||||||
|
EOpAtomicCounterOr,
|
||||||
|
EOpAtomicCounterXor,
|
||||||
|
EOpAtomicCounterExchange,
|
||||||
|
EOpAtomicCounterCompSwap,
|
||||||
|
|
||||||
EOpAny,
|
EOpAny,
|
||||||
EOpAll,
|
EOpAll,
|
||||||
|
@ -325,6 +627,10 @@ enum TOperator {
|
||||||
EOpConstructGuardStart,
|
EOpConstructGuardStart,
|
||||||
EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
|
EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
|
||||||
EOpConstructUint,
|
EOpConstructUint,
|
||||||
|
EOpConstructInt8,
|
||||||
|
EOpConstructUint8,
|
||||||
|
EOpConstructInt16,
|
||||||
|
EOpConstructUint16,
|
||||||
EOpConstructInt64,
|
EOpConstructInt64,
|
||||||
EOpConstructUint64,
|
EOpConstructUint64,
|
||||||
EOpConstructBool,
|
EOpConstructBool,
|
||||||
|
@ -339,6 +645,18 @@ enum TOperator {
|
||||||
EOpConstructBVec2,
|
EOpConstructBVec2,
|
||||||
EOpConstructBVec3,
|
EOpConstructBVec3,
|
||||||
EOpConstructBVec4,
|
EOpConstructBVec4,
|
||||||
|
EOpConstructI8Vec2,
|
||||||
|
EOpConstructI8Vec3,
|
||||||
|
EOpConstructI8Vec4,
|
||||||
|
EOpConstructU8Vec2,
|
||||||
|
EOpConstructU8Vec3,
|
||||||
|
EOpConstructU8Vec4,
|
||||||
|
EOpConstructI16Vec2,
|
||||||
|
EOpConstructI16Vec3,
|
||||||
|
EOpConstructI16Vec4,
|
||||||
|
EOpConstructU16Vec2,
|
||||||
|
EOpConstructU16Vec3,
|
||||||
|
EOpConstructU16Vec4,
|
||||||
EOpConstructIVec2,
|
EOpConstructIVec2,
|
||||||
EOpConstructIVec3,
|
EOpConstructIVec3,
|
||||||
EOpConstructIVec4,
|
EOpConstructIVec4,
|
||||||
|
@ -369,8 +687,49 @@ enum TOperator {
|
||||||
EOpConstructDMat4x2,
|
EOpConstructDMat4x2,
|
||||||
EOpConstructDMat4x3,
|
EOpConstructDMat4x3,
|
||||||
EOpConstructDMat4x4,
|
EOpConstructDMat4x4,
|
||||||
|
EOpConstructIMat2x2,
|
||||||
|
EOpConstructIMat2x3,
|
||||||
|
EOpConstructIMat2x4,
|
||||||
|
EOpConstructIMat3x2,
|
||||||
|
EOpConstructIMat3x3,
|
||||||
|
EOpConstructIMat3x4,
|
||||||
|
EOpConstructIMat4x2,
|
||||||
|
EOpConstructIMat4x3,
|
||||||
|
EOpConstructIMat4x4,
|
||||||
|
EOpConstructUMat2x2,
|
||||||
|
EOpConstructUMat2x3,
|
||||||
|
EOpConstructUMat2x4,
|
||||||
|
EOpConstructUMat3x2,
|
||||||
|
EOpConstructUMat3x3,
|
||||||
|
EOpConstructUMat3x4,
|
||||||
|
EOpConstructUMat4x2,
|
||||||
|
EOpConstructUMat4x3,
|
||||||
|
EOpConstructUMat4x4,
|
||||||
|
EOpConstructBMat2x2,
|
||||||
|
EOpConstructBMat2x3,
|
||||||
|
EOpConstructBMat2x4,
|
||||||
|
EOpConstructBMat3x2,
|
||||||
|
EOpConstructBMat3x3,
|
||||||
|
EOpConstructBMat3x4,
|
||||||
|
EOpConstructBMat4x2,
|
||||||
|
EOpConstructBMat4x3,
|
||||||
|
EOpConstructBMat4x4,
|
||||||
|
EOpConstructFloat16,
|
||||||
|
EOpConstructF16Vec2,
|
||||||
|
EOpConstructF16Vec3,
|
||||||
|
EOpConstructF16Vec4,
|
||||||
|
EOpConstructF16Mat2x2,
|
||||||
|
EOpConstructF16Mat2x3,
|
||||||
|
EOpConstructF16Mat2x4,
|
||||||
|
EOpConstructF16Mat3x2,
|
||||||
|
EOpConstructF16Mat3x3,
|
||||||
|
EOpConstructF16Mat3x4,
|
||||||
|
EOpConstructF16Mat4x2,
|
||||||
|
EOpConstructF16Mat4x3,
|
||||||
|
EOpConstructF16Mat4x4,
|
||||||
EOpConstructStruct,
|
EOpConstructStruct,
|
||||||
EOpConstructTextureSampler,
|
EOpConstructTextureSampler,
|
||||||
|
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
|
||||||
EOpConstructGuardEnd,
|
EOpConstructGuardEnd,
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -397,7 +756,11 @@ enum TOperator {
|
||||||
// Array operators
|
// Array operators
|
||||||
//
|
//
|
||||||
|
|
||||||
EOpArrayLength, // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well.
|
// Can apply to arrays, vectors, or matrices.
|
||||||
|
// Can be decomposed to a constant at compile time, but this does not always happen,
|
||||||
|
// due to link-time effects. So, consumer can expect either a link-time sized or
|
||||||
|
// run-time sized array.
|
||||||
|
EOpArrayLength,
|
||||||
|
|
||||||
//
|
//
|
||||||
// Image operations
|
// Image operations
|
||||||
|
@ -409,6 +772,10 @@ enum TOperator {
|
||||||
EOpImageQuerySamples,
|
EOpImageQuerySamples,
|
||||||
EOpImageLoad,
|
EOpImageLoad,
|
||||||
EOpImageStore,
|
EOpImageStore,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpImageLoadLod,
|
||||||
|
EOpImageStoreLod,
|
||||||
|
#endif
|
||||||
EOpImageAtomicAdd,
|
EOpImageAtomicAdd,
|
||||||
EOpImageAtomicMin,
|
EOpImageAtomicMin,
|
||||||
EOpImageAtomicMax,
|
EOpImageAtomicMax,
|
||||||
|
@ -421,6 +788,9 @@ enum TOperator {
|
||||||
EOpSubpassLoad,
|
EOpSubpassLoad,
|
||||||
EOpSubpassLoadMS,
|
EOpSubpassLoadMS,
|
||||||
EOpSparseImageLoad,
|
EOpSparseImageLoad,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpSparseImageLoadLod,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpImageGuardEnd,
|
EOpImageGuardEnd,
|
||||||
|
|
||||||
|
@ -434,6 +804,9 @@ enum TOperator {
|
||||||
EOpTextureQueryLod,
|
EOpTextureQueryLod,
|
||||||
EOpTextureQueryLevels,
|
EOpTextureQueryLevels,
|
||||||
EOpTextureQuerySamples,
|
EOpTextureQuerySamples,
|
||||||
|
|
||||||
|
EOpSamplingGuardBegin,
|
||||||
|
|
||||||
EOpTexture,
|
EOpTexture,
|
||||||
EOpTextureProj,
|
EOpTextureProj,
|
||||||
EOpTextureLod,
|
EOpTextureLod,
|
||||||
|
@ -455,6 +828,13 @@ enum TOperator {
|
||||||
EOpTextureOffsetClamp,
|
EOpTextureOffsetClamp,
|
||||||
EOpTextureGradClamp,
|
EOpTextureGradClamp,
|
||||||
EOpTextureGradOffsetClamp,
|
EOpTextureGradOffsetClamp,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpTextureGatherLod,
|
||||||
|
EOpTextureGatherLodOffset,
|
||||||
|
EOpTextureGatherLodOffsets,
|
||||||
|
EOpFragmentMaskFetch,
|
||||||
|
EOpFragmentFetch,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpSparseTextureGuardBegin,
|
EOpSparseTextureGuardBegin,
|
||||||
|
|
||||||
|
@ -474,9 +854,14 @@ enum TOperator {
|
||||||
EOpSparseTextureOffsetClamp,
|
EOpSparseTextureOffsetClamp,
|
||||||
EOpSparseTextureGradClamp,
|
EOpSparseTextureGradClamp,
|
||||||
EOpSparseTextureGradOffsetClamp,
|
EOpSparseTextureGradOffsetClamp,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
EOpSparseTextureGatherLod,
|
||||||
|
EOpSparseTextureGatherLodOffset,
|
||||||
|
EOpSparseTextureGatherLodOffsets,
|
||||||
|
#endif
|
||||||
|
|
||||||
EOpSparseTextureGuardEnd,
|
EOpSparseTextureGuardEnd,
|
||||||
|
EOpSamplingGuardEnd,
|
||||||
EOpTextureGuardEnd,
|
EOpTextureGuardEnd,
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -516,7 +901,8 @@ enum TOperator {
|
||||||
EOpInterlockedOr, // ...
|
EOpInterlockedOr, // ...
|
||||||
EOpInterlockedXor, // ...
|
EOpInterlockedXor, // ...
|
||||||
EOpAllMemoryBarrierWithGroupSync, // memory barriers without non-hlsl AST equivalents
|
EOpAllMemoryBarrierWithGroupSync, // memory barriers without non-hlsl AST equivalents
|
||||||
EOpGroupMemoryBarrierWithGroupSync, // ...
|
EOpDeviceMemoryBarrier, // ...
|
||||||
|
EOpDeviceMemoryBarrierWithGroupSync, // ...
|
||||||
EOpWorkgroupMemoryBarrier, // ...
|
EOpWorkgroupMemoryBarrier, // ...
|
||||||
EOpWorkgroupMemoryBarrierWithGroupSync, // ...
|
EOpWorkgroupMemoryBarrierWithGroupSync, // ...
|
||||||
EOpEvaluateAttributeSnapped, // InterpolateAtOffset with int position on 16x16 grid
|
EOpEvaluateAttributeSnapped, // InterpolateAtOffset with int position on 16x16 grid
|
||||||
|
@ -525,6 +911,7 @@ enum TOperator {
|
||||||
EOpLit, // HLSL lighting coefficient vector
|
EOpLit, // HLSL lighting coefficient vector
|
||||||
EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture
|
EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture
|
||||||
EOpAsDouble, // slightly different from EOpUint64BitsToDouble
|
EOpAsDouble, // slightly different from EOpUint64BitsToDouble
|
||||||
|
EOpD3DCOLORtoUBYTE4, // convert and swizzle 4-component color to UBYTE4 range
|
||||||
|
|
||||||
EOpMethodSample, // Texture object methods. These are translated to existing
|
EOpMethodSample, // Texture object methods. These are translated to existing
|
||||||
EOpMethodSampleBias, // AST methods, and exist to represent HLSL semantics until that
|
EOpMethodSampleBias, // AST methods, and exist to represent HLSL semantics until that
|
||||||
|
@ -538,6 +925,43 @@ enum TOperator {
|
||||||
EOpMethodGather, // ...
|
EOpMethodGather, // ...
|
||||||
EOpMethodCalculateLevelOfDetail, // ...
|
EOpMethodCalculateLevelOfDetail, // ...
|
||||||
EOpMethodCalculateLevelOfDetailUnclamped, // ...
|
EOpMethodCalculateLevelOfDetailUnclamped, // ...
|
||||||
|
|
||||||
|
// Load already defined above for textures
|
||||||
|
EOpMethodLoad2, // Structure buffer object methods. These are translated to existing
|
||||||
|
EOpMethodLoad3, // AST methods, and exist to represent HLSL semantics until that
|
||||||
|
EOpMethodLoad4, // translation is performed. See HlslParseContext::decomposeSampleMethods().
|
||||||
|
EOpMethodStore, // ...
|
||||||
|
EOpMethodStore2, // ...
|
||||||
|
EOpMethodStore3, // ...
|
||||||
|
EOpMethodStore4, // ...
|
||||||
|
EOpMethodIncrementCounter, // ...
|
||||||
|
EOpMethodDecrementCounter, // ...
|
||||||
|
// EOpMethodAppend is defined for geo shaders below
|
||||||
|
EOpMethodConsume,
|
||||||
|
|
||||||
|
// SM5 texture methods
|
||||||
|
EOpMethodGatherRed, // These are covered under the above EOpMethodSample comment about
|
||||||
|
EOpMethodGatherGreen, // translation to existing AST opcodes. They exist temporarily
|
||||||
|
EOpMethodGatherBlue, // because HLSL arguments are slightly different.
|
||||||
|
EOpMethodGatherAlpha, // ...
|
||||||
|
EOpMethodGatherCmp, // ...
|
||||||
|
EOpMethodGatherCmpRed, // ...
|
||||||
|
EOpMethodGatherCmpGreen, // ...
|
||||||
|
EOpMethodGatherCmpBlue, // ...
|
||||||
|
EOpMethodGatherCmpAlpha, // ...
|
||||||
|
|
||||||
|
// geometry methods
|
||||||
|
EOpMethodAppend, // Geometry shader methods
|
||||||
|
EOpMethodRestartStrip, // ...
|
||||||
|
|
||||||
|
// matrix
|
||||||
|
EOpMatrixSwizzle, // select multiple matrix components (non-column)
|
||||||
|
|
||||||
|
// SM6 wave ops
|
||||||
|
EOpWaveGetLaneCount, // Will decompose to gl_SubgroupSize.
|
||||||
|
EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID.
|
||||||
|
EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()).
|
||||||
|
EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
|
||||||
};
|
};
|
||||||
|
|
||||||
class TIntermTraverser;
|
class TIntermTraverser;
|
||||||
|
@ -552,6 +976,7 @@ class TIntermBranch;
|
||||||
class TIntermTyped;
|
class TIntermTyped;
|
||||||
class TIntermMethod;
|
class TIntermMethod;
|
||||||
class TIntermSymbol;
|
class TIntermSymbol;
|
||||||
|
class TIntermLoop;
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
@ -579,6 +1004,7 @@ public:
|
||||||
virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
|
virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
|
||||||
virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
|
virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
|
||||||
virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
|
virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
|
||||||
|
virtual glslang::TIntermLoop* getAsLoopNode() { return 0; }
|
||||||
|
|
||||||
virtual const glslang::TIntermTyped* getAsTyped() const { return 0; }
|
virtual const glslang::TIntermTyped* getAsTyped() const { return 0; }
|
||||||
virtual const glslang::TIntermOperator* getAsOperator() const { return 0; }
|
virtual const glslang::TIntermOperator* getAsOperator() const { return 0; }
|
||||||
|
@ -591,6 +1017,7 @@ public:
|
||||||
virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; }
|
virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; }
|
||||||
virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; }
|
virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; }
|
||||||
virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; }
|
virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; }
|
||||||
|
virtual const glslang::TIntermLoop* getAsLoopNode() const { return 0; }
|
||||||
virtual ~TIntermNode() { }
|
virtual ~TIntermNode() { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -634,6 +1061,8 @@ public:
|
||||||
virtual bool isVector() const { return type.isVector(); }
|
virtual bool isVector() const { return type.isVector(); }
|
||||||
virtual bool isScalar() const { return type.isScalar(); }
|
virtual bool isScalar() const { return type.isScalar(); }
|
||||||
virtual bool isStruct() const { return type.isStruct(); }
|
virtual bool isStruct() const { return type.isStruct(); }
|
||||||
|
virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
|
||||||
|
virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
|
||||||
TString getCompleteString() const { return type.getCompleteString(); }
|
TString getCompleteString() const { return type.getCompleteString(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -650,17 +1079,37 @@ public:
|
||||||
body(aBody),
|
body(aBody),
|
||||||
test(aTest),
|
test(aTest),
|
||||||
terminal(aTerminal),
|
terminal(aTerminal),
|
||||||
first(testFirst) { }
|
first(testFirst),
|
||||||
|
unroll(false),
|
||||||
|
dontUnroll(false),
|
||||||
|
dependency(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual TIntermLoop* getAsLoopNode() { return this; }
|
||||||
|
virtual const TIntermLoop* getAsLoopNode() const { return this; }
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
TIntermNode* getBody() const { return body; }
|
TIntermNode* getBody() const { return body; }
|
||||||
TIntermTyped* getTest() const { return test; }
|
TIntermTyped* getTest() const { return test; }
|
||||||
TIntermTyped* getTerminal() const { return terminal; }
|
TIntermTyped* getTerminal() const { return terminal; }
|
||||||
bool testFirst() const { return first; }
|
bool testFirst() const { return first; }
|
||||||
|
|
||||||
|
void setUnroll() { unroll = true; }
|
||||||
|
void setDontUnroll() { dontUnroll = true; }
|
||||||
|
bool getUnroll() const { return unroll; }
|
||||||
|
bool getDontUnroll() const { return dontUnroll; }
|
||||||
|
|
||||||
|
static const unsigned int dependencyInfinite = 0xFFFFFFFF;
|
||||||
|
void setLoopDependency(int d) { dependency = d; }
|
||||||
|
int getLoopDependency() const { return dependency; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermNode* body; // code to loop over
|
TIntermNode* body; // code to loop over
|
||||||
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
|
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
|
||||||
TIntermTyped* terminal; // exists for for-loops
|
TIntermTyped* terminal; // exists for for-loops
|
||||||
bool first; // true for while and for, not for do-while
|
bool first; // true for while and for, not for do-while
|
||||||
|
bool unroll; // true if unroll requested
|
||||||
|
bool dontUnroll; // true if request to not unroll
|
||||||
|
unsigned int dependency; // loop dependency hint; 0 means not set or unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -708,7 +1157,11 @@ public:
|
||||||
// per process threadPoolAllocator, then it causes increased memory usage per compile
|
// per process threadPoolAllocator, then it causes increased memory usage per compile
|
||||||
// it is essential to use "symbol = sym" to assign to symbol
|
// it is essential to use "symbol = sym" to assign to symbol
|
||||||
TIntermSymbol(int i, const TString& n, const TType& t)
|
TIntermSymbol(int i, const TString& n, const TType& t)
|
||||||
: TIntermTyped(t), id(i), constSubtree(nullptr)
|
: TIntermTyped(t), id(i),
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
|
flattenSubset(-1),
|
||||||
|
#endif
|
||||||
|
constSubtree(nullptr)
|
||||||
{ name = n; }
|
{ name = n; }
|
||||||
virtual int getId() const { return id; }
|
virtual int getId() const { return id; }
|
||||||
virtual const TString& getName() const { return name; }
|
virtual const TString& getName() const { return name; }
|
||||||
|
@ -719,9 +1172,20 @@ public:
|
||||||
const TConstUnionArray& getConstArray() const { return constArray; }
|
const TConstUnionArray& getConstArray() const { return constArray; }
|
||||||
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
||||||
TIntermTyped* getConstSubtree() const { return constSubtree; }
|
TIntermTyped* getConstSubtree() const { return constSubtree; }
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
|
void setFlattenSubset(int subset) { flattenSubset = subset; }
|
||||||
|
int getFlattenSubset() const { return flattenSubset; } // -1 means full object
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This is meant for cases where a node has already been constructed, and
|
||||||
|
// later on, it becomes necessary to switch to a different symbol.
|
||||||
|
virtual void switchId(int newId) { id = newId; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int id; // the unique id of the symbol this node represents
|
int id; // the unique id of the symbol this node represents
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
|
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
|
||||||
|
#endif
|
||||||
TString name; // the name of the symbol this node represents
|
TString name; // the name of the symbol this node represents
|
||||||
TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
|
TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
|
||||||
TIntermTyped* constSubtree;
|
TIntermTyped* constSubtree;
|
||||||
|
@ -759,6 +1223,9 @@ struct TCrackedTextureOp {
|
||||||
bool grad;
|
bool grad;
|
||||||
bool subpass;
|
bool subpass;
|
||||||
bool lodClamp;
|
bool lodClamp;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
bool fragMask;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -769,14 +1236,30 @@ public:
|
||||||
virtual TIntermOperator* getAsOperator() { return this; }
|
virtual TIntermOperator* getAsOperator() { return this; }
|
||||||
virtual const TIntermOperator* getAsOperator() const { return this; }
|
virtual const TIntermOperator* getAsOperator() const { return this; }
|
||||||
TOperator getOp() const { return op; }
|
TOperator getOp() const { return op; }
|
||||||
virtual bool promote() { return true; }
|
void setOp(TOperator newOp) { op = newOp; }
|
||||||
bool modifiesState() const;
|
bool modifiesState() const;
|
||||||
bool isConstructor() const;
|
bool isConstructor() const;
|
||||||
bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
|
bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
|
||||||
|
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
|
||||||
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
|
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
|
||||||
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
||||||
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
||||||
|
|
||||||
|
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
|
||||||
|
TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
|
||||||
|
operationPrecision :
|
||||||
|
type.getQualifier().precision; }
|
||||||
|
TString getCompleteString() const
|
||||||
|
{
|
||||||
|
TString cs = type.getCompleteString();
|
||||||
|
if (getOperationPrecision() != type.getQualifier().precision) {
|
||||||
|
cs += ", operation at ";
|
||||||
|
cs += GetPrecisionQualifierString(getOperationPrecision());
|
||||||
|
}
|
||||||
|
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
// Crack the op into the individual dimensions of texturing operation.
|
// Crack the op into the individual dimensions of texturing operation.
|
||||||
void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
|
void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
|
||||||
{
|
{
|
||||||
|
@ -790,6 +1273,9 @@ public:
|
||||||
cracked.grad = false;
|
cracked.grad = false;
|
||||||
cracked.subpass = false;
|
cracked.subpass = false;
|
||||||
cracked.lodClamp = false;
|
cracked.lodClamp = false;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
cracked.fragMask = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EOpImageQuerySize:
|
case EOpImageQuerySize:
|
||||||
|
@ -898,6 +1384,38 @@ public:
|
||||||
cracked.gather = true;
|
cracked.gather = true;
|
||||||
cracked.offsets = true;
|
cracked.offsets = true;
|
||||||
break;
|
break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpTextureGatherLod:
|
||||||
|
case EOpSparseTextureGatherLod:
|
||||||
|
cracked.gather = true;
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
case EOpTextureGatherLodOffset:
|
||||||
|
case EOpSparseTextureGatherLodOffset:
|
||||||
|
cracked.gather = true;
|
||||||
|
cracked.offset = true;
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
case EOpTextureGatherLodOffsets:
|
||||||
|
case EOpSparseTextureGatherLodOffsets:
|
||||||
|
cracked.gather = true;
|
||||||
|
cracked.offsets = true;
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
case EOpImageLoadLod:
|
||||||
|
case EOpImageStoreLod:
|
||||||
|
case EOpSparseImageLoadLod:
|
||||||
|
cracked.lod = true;
|
||||||
|
break;
|
||||||
|
case EOpFragmentMaskFetch:
|
||||||
|
cracked.subpass = sampler.dim == EsdSubpass;
|
||||||
|
cracked.fragMask = true;
|
||||||
|
break;
|
||||||
|
case EOpFragmentFetch:
|
||||||
|
cracked.subpass = sampler.dim == EsdSubpass;
|
||||||
|
cracked.fragMask = true;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case EOpSubpassLoad:
|
case EOpSubpassLoad:
|
||||||
case EOpSubpassLoadMS:
|
case EOpSubpassLoadMS:
|
||||||
cracked.subpass = true;
|
cracked.subpass = true;
|
||||||
|
@ -908,9 +1426,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o) {}
|
TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o), operationPrecision(EpqNone) {}
|
||||||
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
|
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o), operationPrecision(EpqNone) {}
|
||||||
TOperator op;
|
TOperator op;
|
||||||
|
// The result precision is in the inherited TType, and is usually meant to be both
|
||||||
|
// the operation precision and the result precision. However, some more complex things,
|
||||||
|
// like built-in function calls, distinguish between the two, in which case non-EqpNone
|
||||||
|
// 'operationPrecision' overrides the result precision as far as operation precision
|
||||||
|
// is concerned.
|
||||||
|
TPrecisionQualifier operationPrecision;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -926,7 +1450,6 @@ public:
|
||||||
virtual TIntermTyped* getRight() const { return right; }
|
virtual TIntermTyped* getRight() const { return right; }
|
||||||
virtual TIntermBinary* getAsBinaryNode() { return this; }
|
virtual TIntermBinary* getAsBinaryNode() { return this; }
|
||||||
virtual const TIntermBinary* getAsBinaryNode() const { return this; }
|
virtual const TIntermBinary* getAsBinaryNode() const { return this; }
|
||||||
virtual bool promote();
|
|
||||||
virtual void updatePrecision();
|
virtual void updatePrecision();
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped* left;
|
TIntermTyped* left;
|
||||||
|
@ -946,21 +1469,20 @@ public:
|
||||||
virtual const TIntermTyped* getOperand() const { return operand; }
|
virtual const TIntermTyped* getOperand() const { return operand; }
|
||||||
virtual TIntermUnary* getAsUnaryNode() { return this; }
|
virtual TIntermUnary* getAsUnaryNode() { return this; }
|
||||||
virtual const TIntermUnary* getAsUnaryNode() const { return this; }
|
virtual const TIntermUnary* getAsUnaryNode() const { return this; }
|
||||||
virtual bool promote();
|
|
||||||
virtual void updatePrecision();
|
virtual void updatePrecision();
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped* operand;
|
TIntermTyped* operand;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TVector<TIntermNode*> TIntermSequence;
|
typedef TVector<TIntermNode*> TIntermSequence;
|
||||||
typedef TVector<int> TQualifierList;
|
typedef TVector<TStorageQualifier> TQualifierList;
|
||||||
//
|
//
|
||||||
// Nodes that operate on an arbitrary sized set of children.
|
// Nodes that operate on an arbitrary sized set of children.
|
||||||
//
|
//
|
||||||
class TIntermAggregate : public TIntermOperator {
|
class TIntermAggregate : public TIntermOperator {
|
||||||
public:
|
public:
|
||||||
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
|
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { }
|
||||||
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
|
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { }
|
||||||
~TIntermAggregate() { delete pragmaTable; }
|
~TIntermAggregate() { delete pragmaTable; }
|
||||||
virtual TIntermAggregate* getAsAggregate() { return this; }
|
virtual TIntermAggregate* getAsAggregate() { return this; }
|
||||||
virtual const TIntermAggregate* getAsAggregate() const { return this; }
|
virtual const TIntermAggregate* getAsAggregate() const { return this; }
|
||||||
|
@ -978,7 +1500,7 @@ public:
|
||||||
void setDebug(bool d) { debug = d; }
|
void setDebug(bool d) { debug = d; }
|
||||||
bool getOptimize() const { return optimize; }
|
bool getOptimize() const { return optimize; }
|
||||||
bool getDebug() const { return debug; }
|
bool getDebug() const { return debug; }
|
||||||
void addToPragmaTable(const TPragmaTable& pTable);
|
void setPragmaTable(const TPragmaTable& pTable);
|
||||||
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
|
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
|
||||||
protected:
|
protected:
|
||||||
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
|
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
|
||||||
|
@ -998,19 +1520,35 @@ protected:
|
||||||
class TIntermSelection : public TIntermTyped {
|
class TIntermSelection : public TIntermTyped {
|
||||||
public:
|
public:
|
||||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
|
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
|
||||||
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
|
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB),
|
||||||
|
shortCircuit(true),
|
||||||
|
flatten(false), dontFlatten(false) {}
|
||||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
|
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
|
||||||
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
|
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB),
|
||||||
|
shortCircuit(true),
|
||||||
|
flatten(false), dontFlatten(false) {}
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermTyped* getCondition() const { return condition; }
|
virtual TIntermTyped* getCondition() const { return condition; }
|
||||||
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
||||||
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
||||||
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
||||||
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
||||||
|
|
||||||
|
void setNoShortCircuit() { shortCircuit = false; }
|
||||||
|
bool getShortCircuit() const { return shortCircuit; }
|
||||||
|
|
||||||
|
void setFlatten() { flatten = true; }
|
||||||
|
void setDontFlatten() { dontFlatten = true; }
|
||||||
|
bool getFlatten() const { return flatten; }
|
||||||
|
bool getDontFlatten() const { return dontFlatten; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped* condition;
|
TIntermTyped* condition;
|
||||||
TIntermNode* trueBlock;
|
TIntermNode* trueBlock;
|
||||||
TIntermNode* falseBlock;
|
TIntermNode* falseBlock;
|
||||||
|
bool shortCircuit; // normally all if-then-else and all GLSL ?: short-circuit, but HLSL ?: does not
|
||||||
|
bool flatten; // true if flatten requested
|
||||||
|
bool dontFlatten; // true if requested to not flatten
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1021,15 +1559,24 @@ protected:
|
||||||
//
|
//
|
||||||
class TIntermSwitch : public TIntermNode {
|
class TIntermSwitch : public TIntermNode {
|
||||||
public:
|
public:
|
||||||
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { }
|
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b),
|
||||||
|
flatten(false), dontFlatten(false) {}
|
||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
virtual TIntermNode* getCondition() const { return condition; }
|
virtual TIntermNode* getCondition() const { return condition; }
|
||||||
virtual TIntermAggregate* getBody() const { return body; }
|
virtual TIntermAggregate* getBody() const { return body; }
|
||||||
virtual TIntermSwitch* getAsSwitchNode() { return this; }
|
virtual TIntermSwitch* getAsSwitchNode() { return this; }
|
||||||
virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
|
virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
|
||||||
|
|
||||||
|
void setFlatten() { flatten = true; }
|
||||||
|
void setDontFlatten() { dontFlatten = true; }
|
||||||
|
bool getFlatten() const { return flatten; }
|
||||||
|
bool getDontFlatten() const { return dontFlatten; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermTyped* condition;
|
TIntermTyped* condition;
|
||||||
TIntermAggregate* body;
|
TIntermAggregate* body;
|
||||||
|
bool flatten; // true if flatten requested
|
||||||
|
bool dontFlatten; // true if requested to not flatten
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TVisit
|
enum TVisit
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// This header is generated by the make-revision script.
|
// This header is generated by the make-revision script.
|
||||||
// For the version, it uses the latest git tag followed by the number of commits.
|
|
||||||
// For the date, it uses the current date (when then script is run).
|
|
||||||
|
|
||||||
#define GLSLANG_REVISION "SPIRV99.947"
|
#define GLSLANG_PATCH_LEVEL 2743
|
||||||
#define GLSLANG_DATE "15-Feb-2016"
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,24 +21,25 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -176,8 +178,40 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
switch (getType().getBasicType()) {
|
switch (getType().getBasicType()) {
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
|
case EbtFloat16:
|
||||||
newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
|
newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
|
||||||
break;
|
break;
|
||||||
|
case EbtInt8:
|
||||||
|
if (rightUnionArray[i] == 0)
|
||||||
|
newConstArray[i].setI8Const(0x7F);
|
||||||
|
else if (rightUnionArray[i].getI8Const() == -1 && leftUnionArray[i].getI8Const() == (signed char)0x80)
|
||||||
|
newConstArray[i].setI8Const((signed char)0x80);
|
||||||
|
else
|
||||||
|
newConstArray[i].setI8Const(leftUnionArray[i].getI8Const() / rightUnionArray[i].getI8Const());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EbtUint8:
|
||||||
|
if (rightUnionArray[i] == 0) {
|
||||||
|
newConstArray[i].setU8Const(0xFF);
|
||||||
|
} else
|
||||||
|
newConstArray[i].setU8Const(leftUnionArray[i].getU8Const() / rightUnionArray[i].getU8Const());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EbtInt16:
|
||||||
|
if (rightUnionArray[i] == 0)
|
||||||
|
newConstArray[i].setI16Const(0x7FFF);
|
||||||
|
else if (rightUnionArray[i].getI16Const() == -1 && leftUnionArray[i].getI16Const() == (signed short)0x8000)
|
||||||
|
newConstArray[i].setI16Const(short(0x8000));
|
||||||
|
else
|
||||||
|
newConstArray[i].setI16Const(leftUnionArray[i].getI16Const() / rightUnionArray[i].getI16Const());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EbtUint16:
|
||||||
|
if (rightUnionArray[i] == 0) {
|
||||||
|
newConstArray[i].setU16Const(0xFFFF);
|
||||||
|
} else
|
||||||
|
newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const());
|
||||||
|
break;
|
||||||
|
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
if (rightUnionArray[i] == 0)
|
if (rightUnionArray[i] == 0)
|
||||||
|
@ -190,7 +224,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
|
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
if (rightUnionArray[i] == 0) {
|
if (rightUnionArray[i] == 0) {
|
||||||
newConstArray[i].setUConst(0xFFFFFFFF);
|
newConstArray[i].setUConst(0xFFFFFFFFu);
|
||||||
} else
|
} else
|
||||||
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
||||||
break;
|
break;
|
||||||
|
@ -243,9 +277,32 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
||||||
for (int i = 0; i < newComps; i++) {
|
for (int i = 0; i < newComps; i++) {
|
||||||
if (rightUnionArray[i] == 0)
|
if (rightUnionArray[i] == 0)
|
||||||
newConstArray[i] = leftUnionArray[i];
|
newConstArray[i] = leftUnionArray[i];
|
||||||
else
|
else {
|
||||||
|
switch (getType().getBasicType()) {
|
||||||
|
case EbtInt:
|
||||||
|
if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == INT_MIN) {
|
||||||
|
newConstArray[i].setIConst(0);
|
||||||
|
break;
|
||||||
|
} else goto modulo_default;
|
||||||
|
|
||||||
|
case EbtInt64:
|
||||||
|
if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) {
|
||||||
|
newConstArray[i].setI64Const(0);
|
||||||
|
break;
|
||||||
|
} else goto modulo_default;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtInt16:
|
||||||
|
if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) {
|
||||||
|
newConstArray[i].setIConst(0);
|
||||||
|
break;
|
||||||
|
} else goto modulo_default;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
modulo_default:
|
||||||
newConstArray[i] = leftUnionArray[i] % rightUnionArray[i];
|
newConstArray[i] = leftUnionArray[i] % rightUnionArray[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EOpRightShift:
|
case EOpRightShift:
|
||||||
|
@ -367,6 +424,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
resultSize = 2;
|
resultSize = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EOpPack16:
|
||||||
|
case EOpPack32:
|
||||||
|
case EOpPack64:
|
||||||
|
case EOpUnpack32:
|
||||||
|
case EOpUnpack16:
|
||||||
|
case EOpUnpack8:
|
||||||
case EOpNormalize:
|
case EOpNormalize:
|
||||||
componentWise = false;
|
componentWise = false;
|
||||||
resultSize = objectSize;
|
resultSize = objectSize;
|
||||||
|
@ -425,6 +488,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
case EOpPackSnorm2x16:
|
case EOpPackSnorm2x16:
|
||||||
case EOpPackUnorm2x16:
|
case EOpPackUnorm2x16:
|
||||||
case EOpPackHalf2x16:
|
case EOpPackHalf2x16:
|
||||||
|
case EOpPack16:
|
||||||
|
case EOpPack32:
|
||||||
|
case EOpPack64:
|
||||||
|
case EOpUnpack32:
|
||||||
|
case EOpUnpack16:
|
||||||
|
case EOpUnpack8:
|
||||||
|
|
||||||
case EOpUnpackSnorm2x16:
|
case EOpUnpackSnorm2x16:
|
||||||
case EOpUnpackUnorm2x16:
|
case EOpUnpackUnorm2x16:
|
||||||
|
@ -450,11 +519,16 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
case EOpNegative:
|
case EOpNegative:
|
||||||
switch (getType().getBasicType()) {
|
switch (getType().getBasicType()) {
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
|
case EbtFloat16:
|
||||||
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
||||||
|
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
|
||||||
|
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
|
||||||
|
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
|
||||||
|
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
|
||||||
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
||||||
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
||||||
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
||||||
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getU64Const()))); break;
|
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -604,7 +678,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
case EOpUintBitsToFloat:
|
case EOpUintBitsToFloat:
|
||||||
case EOpDoubleBitsToInt64:
|
case EOpDoubleBitsToInt64:
|
||||||
case EOpDoubleBitsToUint64:
|
case EOpDoubleBitsToUint64:
|
||||||
|
case EOpInt64BitsToDouble:
|
||||||
|
case EOpUint64BitsToDouble:
|
||||||
|
case EOpFloat16BitsToInt16:
|
||||||
|
case EOpFloat16BitsToUint16:
|
||||||
|
case EOpInt16BitsToFloat16:
|
||||||
|
case EOpUint16BitsToFloat16:
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -623,6 +702,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
{
|
{
|
||||||
|
if (aggrNode == nullptr)
|
||||||
|
return aggrNode;
|
||||||
|
|
||||||
if (! areAllChildConst(aggrNode))
|
if (! areAllChildConst(aggrNode))
|
||||||
return aggrNode;
|
return aggrNode;
|
||||||
|
|
||||||
|
@ -685,14 +767,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
for (unsigned int arg = 0; arg < children.size(); ++arg)
|
for (unsigned int arg = 0; arg < children.size(); ++arg)
|
||||||
childConstUnions.push_back(children[arg]->getAsConstantUnion()->getConstArray());
|
childConstUnions.push_back(children[arg]->getAsConstantUnion()->getConstArray());
|
||||||
|
|
||||||
// Second, do the actual folding
|
|
||||||
|
|
||||||
bool isFloatingPoint = children[0]->getAsTyped()->getBasicType() == EbtFloat ||
|
|
||||||
children[0]->getAsTyped()->getBasicType() == EbtDouble;
|
|
||||||
bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt ||
|
|
||||||
children[0]->getAsTyped()->getBasicType() == EbtInt64;
|
|
||||||
bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 ||
|
|
||||||
children[0]->getAsTyped()->getBasicType() == EbtUint64;
|
|
||||||
if (componentwise) {
|
if (componentwise) {
|
||||||
for (int comp = 0; comp < objectSize; comp++) {
|
for (int comp = 0; comp < objectSize; comp++) {
|
||||||
|
|
||||||
|
@ -713,53 +787,114 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
break;
|
break;
|
||||||
case EOpMin:
|
case EOpMin:
|
||||||
if (isFloatingPoint)
|
switch(children[0]->getAsTyped()->getBasicType()) {
|
||||||
|
case EbtFloat16:
|
||||||
|
case EbtFloat:
|
||||||
|
case EbtDouble:
|
||||||
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
else if (isSigned) {
|
break;
|
||||||
if (isInt64)
|
case EbtInt8:
|
||||||
newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
||||||
else
|
break;
|
||||||
|
case EbtUint8:
|
||||||
|
newConstArray[comp].setU8Const(std::min(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()));
|
||||||
|
break;
|
||||||
|
case EbtInt16:
|
||||||
|
newConstArray[comp].setI16Const(std::min(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()));
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
||||||
|
break;
|
||||||
|
case EbtInt:
|
||||||
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
||||||
} else {
|
break;
|
||||||
if (isInt64)
|
case EbtUint:
|
||||||
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
|
||||||
else
|
|
||||||
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
||||||
|
break;
|
||||||
|
case EbtInt64:
|
||||||
|
newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
||||||
|
break;
|
||||||
|
case EbtUint64:
|
||||||
|
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
||||||
|
break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOpMax:
|
case EOpMax:
|
||||||
if (isFloatingPoint)
|
switch(children[0]->getAsTyped()->getBasicType()) {
|
||||||
|
case EbtFloat16:
|
||||||
|
case EbtFloat:
|
||||||
|
case EbtDouble:
|
||||||
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
else if (isSigned) {
|
break;
|
||||||
if (isInt64)
|
case EbtInt8:
|
||||||
newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
||||||
else
|
break;
|
||||||
|
case EbtUint8:
|
||||||
|
newConstArray[comp].setU8Const(std::max(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()));
|
||||||
|
break;
|
||||||
|
case EbtInt16:
|
||||||
|
newConstArray[comp].setI16Const(std::max(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()));
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
||||||
|
break;
|
||||||
|
case EbtInt:
|
||||||
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
||||||
} else {
|
break;
|
||||||
if (isInt64)
|
case EbtUint:
|
||||||
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
|
||||||
else
|
|
||||||
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
||||||
|
break;
|
||||||
|
case EbtInt64:
|
||||||
|
newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
||||||
|
break;
|
||||||
|
case EbtUint64:
|
||||||
|
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
||||||
|
break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOpClamp:
|
case EOpClamp:
|
||||||
if (isFloatingPoint)
|
switch(children[0]->getAsTyped()->getBasicType()) {
|
||||||
|
case EbtFloat16:
|
||||||
|
case EbtFloat:
|
||||||
|
case EbtDouble:
|
||||||
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
|
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
|
||||||
childConstUnions[2][arg2comp].getDConst()));
|
childConstUnions[2][arg2comp].getDConst()));
|
||||||
else if (isSigned) {
|
break;
|
||||||
if (isInt64)
|
case EbtInt8:
|
||||||
newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
|
newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()),
|
||||||
childConstUnions[2][arg2comp].getI64Const()));
|
childConstUnions[2][arg2comp].getI8Const()));
|
||||||
else
|
break;
|
||||||
|
case EbtUint8:
|
||||||
|
newConstArray[comp].setU8Const(std::min(std::max(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()),
|
||||||
|
childConstUnions[2][arg2comp].getU8Const()));
|
||||||
|
break;
|
||||||
|
case EbtInt16:
|
||||||
|
newConstArray[comp].setI16Const(std::min(std::max(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()),
|
||||||
|
childConstUnions[2][arg2comp].getI16Const()));
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
newConstArray[comp].setU16Const(std::min(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()),
|
||||||
|
childConstUnions[2][arg2comp].getU16Const()));
|
||||||
|
break;
|
||||||
|
case EbtInt:
|
||||||
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
|
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
|
||||||
childConstUnions[2][arg2comp].getIConst()));
|
childConstUnions[2][arg2comp].getIConst()));
|
||||||
} else {
|
break;
|
||||||
if (isInt64)
|
case EbtUint:
|
||||||
newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
|
|
||||||
childConstUnions[2][arg2comp].getU64Const()));
|
|
||||||
else
|
|
||||||
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
|
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
|
||||||
childConstUnions[2][arg2comp].getUConst()));
|
childConstUnions[2][arg2comp].getUConst()));
|
||||||
|
break;
|
||||||
|
case EbtInt64:
|
||||||
|
newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
|
||||||
|
childConstUnions[2][arg2comp].getI64Const()));
|
||||||
|
break;
|
||||||
|
case EbtUint64:
|
||||||
|
newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
|
||||||
|
childConstUnions[2][arg2comp].getU64Const()));
|
||||||
|
break;
|
||||||
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOpLessThan:
|
case EOpLessThan:
|
||||||
|
@ -832,7 +967,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
||||||
newConstArray[2] = childConstUnions[0][0] * childConstUnions[1][1] - childConstUnions[0][1] * childConstUnions[1][0];
|
newConstArray[2] = childConstUnions[0][0] * childConstUnions[1][1] - childConstUnions[0][1] * childConstUnions[1][0];
|
||||||
break;
|
break;
|
||||||
case EOpFaceForward:
|
case EOpFaceForward:
|
||||||
// If dot(Nref, I) < 0 return N, otherwise return –N: Arguments are (N, I, Nref).
|
// If dot(Nref, I) < 0 return N, otherwise return -N: Arguments are (N, I, Nref).
|
||||||
dot = childConstUnions[1].dot(childConstUnions[2]);
|
dot = childConstUnions[1].dot(childConstUnions[2]);
|
||||||
for (int comp = 0; comp < numComps; ++comp) {
|
for (int comp = 0; comp < numComps; ++comp) {
|
||||||
if (dot < 0.0)
|
if (dot < 0.0)
|
||||||
|
@ -962,20 +1097,20 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons
|
||||||
// Make a constant vector node or constant scalar node, representing a given
|
// Make a constant vector node or constant scalar node, representing a given
|
||||||
// constant vector and constant swizzle into it.
|
// constant vector and constant swizzle into it.
|
||||||
//
|
//
|
||||||
TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc& loc)
|
TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& selectors, const TSourceLoc& loc)
|
||||||
{
|
{
|
||||||
const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray();
|
const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray();
|
||||||
TConstUnionArray constArray(fields.num);
|
TConstUnionArray constArray(selectors.size());
|
||||||
|
|
||||||
for (int i = 0; i < fields.num; i++)
|
for (int i = 0; i < selectors.size(); i++)
|
||||||
constArray[i] = unionArray[fields.offsets[i]];
|
constArray[i] = unionArray[selectors[i]];
|
||||||
|
|
||||||
TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc);
|
TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc);
|
||||||
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
result = node;
|
result = node;
|
||||||
else
|
else
|
||||||
result->setType(TType(node->getBasicType(), EvqConst, fields.num));
|
result->setType(TType(node->getBasicType(), EvqConst, selectors.size()));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,32 +18,36 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../Include/InfoSink.h"
|
#include "../Include/InfoSink.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
void TInfoSinkBase::append(const char* s)
|
void TInfoSinkBase::append(const char* s)
|
||||||
{
|
{
|
||||||
if (outputStream & EString) {
|
if (outputStream & EString) {
|
||||||
|
if (s == nullptr)
|
||||||
|
sink.append("(null)");
|
||||||
|
else {
|
||||||
checkMem(strlen(s));
|
checkMem(strlen(s));
|
||||||
sink.append(s);
|
sink.append(s);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//#ifdef _WIN32
|
//#ifdef _WIN32
|
||||||
// if (outputStream & EDebugger)
|
// if (outputStream & EDebugger)
|
||||||
|
|
4728
Externals/glslang/glslang/MachineIndependent/Initialize.cpp
vendored
Normal file → Executable file
4728
Externals/glslang/glslang/MachineIndependent/Initialize.cpp
vendored
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013-2016 LunarG, Inc.
|
// Copyright (C) 2013-2016 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _INITIALIZE_INCLUDED_
|
#ifndef _INITIALIZE_INCLUDED_
|
||||||
|
@ -67,7 +67,6 @@ public:
|
||||||
virtual const TString& getStageString(EShLanguage language) const { return stageBuiltins[language]; }
|
virtual const TString& getStageString(EShLanguage language) const { return stageBuiltins[language]; }
|
||||||
|
|
||||||
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) = 0;
|
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) = 0;
|
||||||
|
|
||||||
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) = 0;
|
virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -89,16 +88,15 @@ public:
|
||||||
void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage);
|
void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage);
|
||||||
|
|
||||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable);
|
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable);
|
||||||
|
|
||||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
|
void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
|
||||||
void addSubpassSampling(TSampler, TString& typeName, int version, EProfile profile);
|
void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addQueryFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addImageFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addImageFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addSamplingFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addSamplingFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addGatherFunctions(TSampler, TString& typeName, int version, EProfile profile);
|
void addGatherFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
|
|
||||||
// Helpers for making textual representations of the permutations
|
// Helpers for making textual representations of the permutations
|
||||||
// of texturing/imaging functions.
|
// of texturing/imaging functions.
|
||||||
|
@ -107,7 +105,6 @@ protected:
|
||||||
int dimMap[EsdNumDims];
|
int dimMap[EsdNumDims];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _INITIALIZE_INCLUDED_
|
#endif // _INITIALIZE_INCLUDED_
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//Copyright (c) 2002-2010 The ANGLE Project Authors.
|
// Copyright (c) 2002-2010 The ANGLE Project Authors.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -21,18 +21,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../Include/intermediate.h"
|
#include "../Include/intermediate.h"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,138 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016 LunarG, 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
|
||||||
|
|
||||||
|
#include "../Include/Common.h"
|
||||||
|
#include "reflection.h"
|
||||||
|
#include "localintermediate.h"
|
||||||
|
|
||||||
|
#include "gl_types.h"
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
//
|
||||||
|
// The traverser: mostly pass through, except
|
||||||
|
// - processing function-call nodes to push live functions onto the stack of functions to process
|
||||||
|
// - processing selection nodes to trim semantically dead code
|
||||||
|
//
|
||||||
|
// This is in the glslang namespace directly so it can be a friend of TReflection.
|
||||||
|
// This can be derived from to implement reflection database traversers or
|
||||||
|
// binding mappers: anything that wants to traverse the live subset of the tree.
|
||||||
|
//
|
||||||
|
|
||||||
|
class TLiveTraverser : public TIntermTraverser {
|
||||||
|
public:
|
||||||
|
TLiveTraverser(const TIntermediate& i, bool traverseAll = false,
|
||||||
|
bool preVisit = true, bool inVisit = false, bool postVisit = false) :
|
||||||
|
TIntermTraverser(preVisit, inVisit, postVisit),
|
||||||
|
intermediate(i), traverseAll(traverseAll)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
//
|
||||||
|
// Given a function name, find its subroot in the tree, and push it onto the stack of
|
||||||
|
// functions left to process.
|
||||||
|
//
|
||||||
|
void pushFunction(const TString& name)
|
||||||
|
{
|
||||||
|
TIntermSequence& globals = intermediate.getTreeRoot()->getAsAggregate()->getSequence();
|
||||||
|
for (unsigned int f = 0; f < globals.size(); ++f) {
|
||||||
|
TIntermAggregate* candidate = globals[f]->getAsAggregate();
|
||||||
|
if (candidate && candidate->getOp() == EOpFunction && candidate->getName() == name) {
|
||||||
|
functions.push_back(candidate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::list<TIntermAggregate*> TFunctionStack;
|
||||||
|
TFunctionStack functions;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// To catch which function calls are not dead, and hence which functions must be visited.
|
||||||
|
virtual bool visitAggregate(TVisit, TIntermAggregate* node)
|
||||||
|
{
|
||||||
|
if (!traverseAll)
|
||||||
|
if (node->getOp() == EOpFunctionCall)
|
||||||
|
addFunctionCall(node);
|
||||||
|
|
||||||
|
return true; // traverse this subtree
|
||||||
|
}
|
||||||
|
|
||||||
|
// To prune semantically dead paths.
|
||||||
|
virtual bool visitSelection(TVisit /* visit */, TIntermSelection* node)
|
||||||
|
{
|
||||||
|
if (traverseAll)
|
||||||
|
return true; // traverse all code
|
||||||
|
|
||||||
|
TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion();
|
||||||
|
if (constant) {
|
||||||
|
// cull the path that is dead
|
||||||
|
if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock())
|
||||||
|
node->getTrueBlock()->traverse(this);
|
||||||
|
if (constant->getConstArray()[0].getBConst() == false && node->getFalseBlock())
|
||||||
|
node->getFalseBlock()->traverse(this);
|
||||||
|
|
||||||
|
return false; // don't traverse any more, we did it all above
|
||||||
|
} else
|
||||||
|
return true; // traverse the whole subtree
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track live functions as well as uniforms, so that we don't visit dead functions
|
||||||
|
// and only visit each function once.
|
||||||
|
void addFunctionCall(TIntermAggregate* call)
|
||||||
|
{
|
||||||
|
// // just use the map to ensure we process each function at most once
|
||||||
|
if (liveFunctions.find(call->getName()) == liveFunctions.end()) {
|
||||||
|
liveFunctions.insert(call->getName());
|
||||||
|
pushFunction(call->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TIntermediate& intermediate;
|
||||||
|
typedef std::unordered_set<TString> TLiveFunctions;
|
||||||
|
TLiveFunctions liveFunctions;
|
||||||
|
bool traverseAll;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// prevent copy & copy construct
|
||||||
|
TLiveTraverser(TLiveTraverser&);
|
||||||
|
TLiveTraverser& operator=(TLiveTraverser&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace glslang
|
|
@ -0,0 +1,613 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
|
// Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Implement the TParseContextBase class.
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
#include "ParseHelper.h"
|
||||||
|
|
||||||
|
extern int yyparse(glslang::TParseContext*);
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Used to output syntax, parsing, and semantic errors.
|
||||||
|
//
|
||||||
|
|
||||||
|
void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReason,
|
||||||
|
const char* szToken,
|
||||||
|
const char* szExtraInfoFormat,
|
||||||
|
TPrefixType prefix, va_list args)
|
||||||
|
{
|
||||||
|
const int maxSize = MaxTokenLength + 200;
|
||||||
|
char szExtraInfo[maxSize];
|
||||||
|
|
||||||
|
safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args);
|
||||||
|
|
||||||
|
infoSink.info.prefix(prefix);
|
||||||
|
infoSink.info.location(loc);
|
||||||
|
infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
|
||||||
|
|
||||||
|
if (prefix == EPrefixError) {
|
||||||
|
++numErrors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...)
|
||||||
|
{
|
||||||
|
if (messages & EShMsgOnlyPreprocessor)
|
||||||
|
return;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, szExtraInfoFormat);
|
||||||
|
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if ((messages & EShMsgCascadingErrors) == 0)
|
||||||
|
currentScanner->setEndOfInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_DECL TParseContextBase::warn(const TSourceLoc& loc, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...)
|
||||||
|
{
|
||||||
|
if (suppressWarnings())
|
||||||
|
return;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, szExtraInfoFormat);
|
||||||
|
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_DECL TParseContextBase::ppError(const TSourceLoc& loc, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, szExtraInfoFormat);
|
||||||
|
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if ((messages & EShMsgCascadingErrors) == 0)
|
||||||
|
currentScanner->setEndOfInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, szExtraInfoFormat);
|
||||||
|
outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Both test and if necessary, spit out an error, to see if the node is really
|
||||||
|
// an l-value that can be operated on this way.
|
||||||
|
//
|
||||||
|
// Returns true if there was an error.
|
||||||
|
//
|
||||||
|
bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
|
||||||
|
{
|
||||||
|
TIntermBinary* binaryNode = node->getAsBinaryNode();
|
||||||
|
|
||||||
|
if (binaryNode) {
|
||||||
|
switch(binaryNode->getOp()) {
|
||||||
|
case EOpIndexDirect:
|
||||||
|
case EOpIndexIndirect: // fall through
|
||||||
|
case EOpIndexDirectStruct: // fall through
|
||||||
|
case EOpVectorSwizzle:
|
||||||
|
case EOpMatrixSwizzle:
|
||||||
|
return lValueErrorCheck(loc, op, binaryNode->getLeft());
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
error(loc, " l-value required", op, "", "");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* symbol = nullptr;
|
||||||
|
TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||||
|
if (symNode != nullptr)
|
||||||
|
symbol = symNode->getName().c_str();
|
||||||
|
|
||||||
|
const char* message = nullptr;
|
||||||
|
switch (node->getQualifier().storage) {
|
||||||
|
case EvqConst: message = "can't modify a const"; break;
|
||||||
|
case EvqConstReadOnly: message = "can't modify a const"; break;
|
||||||
|
case EvqUniform: message = "can't modify a uniform"; break;
|
||||||
|
case EvqBuffer:
|
||||||
|
if (node->getQualifier().readonly)
|
||||||
|
message = "can't modify a readonly buffer";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
//
|
||||||
|
// Type that can't be written to?
|
||||||
|
//
|
||||||
|
switch (node->getBasicType()) {
|
||||||
|
case EbtSampler:
|
||||||
|
message = "can't modify a sampler";
|
||||||
|
break;
|
||||||
|
case EbtAtomicUint:
|
||||||
|
message = "can't modify an atomic_uint";
|
||||||
|
break;
|
||||||
|
case EbtVoid:
|
||||||
|
message = "can't modify void";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message == nullptr && binaryNode == nullptr && symNode == nullptr) {
|
||||||
|
error(loc, " l-value required", op, "", "");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Everything else is okay, no error.
|
||||||
|
//
|
||||||
|
if (message == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//
|
||||||
|
// If we get here, we have an error and a message.
|
||||||
|
//
|
||||||
|
if (symNode)
|
||||||
|
error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
|
||||||
|
else
|
||||||
|
error(loc, " l-value required", op, "(%s)", message);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for and give an error if the node can't be read from.
|
||||||
|
void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
|
||||||
|
{
|
||||||
|
if (! node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TIntermBinary* binaryNode = node->getAsBinaryNode();
|
||||||
|
if (binaryNode) {
|
||||||
|
switch(binaryNode->getOp()) {
|
||||||
|
case EOpIndexDirect:
|
||||||
|
case EOpIndexIndirect:
|
||||||
|
case EOpIndexDirectStruct:
|
||||||
|
case EOpVectorSwizzle:
|
||||||
|
case EOpMatrixSwizzle:
|
||||||
|
rValueErrorCheck(loc, op, binaryNode->getLeft());
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TIntermSymbol* symNode = node->getAsSymbolNode();
|
||||||
|
if (symNode && symNode->getQualifier().writeonly)
|
||||||
|
error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add 'symbol' to the list of deferred linkage symbols, which
|
||||||
|
// are later processed in finish(), at which point the symbol
|
||||||
|
// must still be valid.
|
||||||
|
// It is okay if the symbol's type will be subsequently edited;
|
||||||
|
// the modifications will be tracked.
|
||||||
|
// Order is preserved, to avoid creating novel forward references.
|
||||||
|
void TParseContextBase::trackLinkage(TSymbol& symbol)
|
||||||
|
{
|
||||||
|
if (!parsingBuiltins)
|
||||||
|
linkageSymbols.push_back(&symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure index is in bounds, correct if necessary.
|
||||||
|
// Give an error if not.
|
||||||
|
void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
|
||||||
|
{
|
||||||
|
if (index < 0) {
|
||||||
|
error(loc, "", "[", "index out of range '%d'", index);
|
||||||
|
index = 0;
|
||||||
|
} else if (type.isArray()) {
|
||||||
|
if (type.isSizedArray() && index >= type.getOuterArraySize()) {
|
||||||
|
error(loc, "", "[", "array index out of range '%d'", index);
|
||||||
|
index = type.getOuterArraySize() - 1;
|
||||||
|
}
|
||||||
|
} else if (type.isVector()) {
|
||||||
|
if (index >= type.getVectorSize()) {
|
||||||
|
error(loc, "", "[", "vector index out of range '%d'", index);
|
||||||
|
index = type.getVectorSize() - 1;
|
||||||
|
}
|
||||||
|
} else if (type.isMatrix()) {
|
||||||
|
if (index >= type.getMatrixCols()) {
|
||||||
|
error(loc, "", "[", "matrix index out of range '%d'", index);
|
||||||
|
index = type.getMatrixCols() - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a shared symbol have a non-shared version that can be edited by the current
|
||||||
|
// compile, such that editing its type will not change the shared version and will
|
||||||
|
// effect all nodes already sharing it (non-shallow type),
|
||||||
|
// or adopting its full type after being edited (shallow type).
|
||||||
|
void TParseContextBase::makeEditable(TSymbol*& symbol)
|
||||||
|
{
|
||||||
|
// copyUp() does a deep copy of the type.
|
||||||
|
symbol = symbolTable.copyUp(symbol);
|
||||||
|
|
||||||
|
// Save it (deferred, so it can be edited first) in the AST for linker use.
|
||||||
|
if (symbol)
|
||||||
|
trackLinkage(*symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a writable version of the variable 'name'.
|
||||||
|
//
|
||||||
|
// Return nullptr if 'name' is not found. This should mean
|
||||||
|
// something is seriously wrong (e.g., compiler asking self for
|
||||||
|
// built-in that doesn't exist).
|
||||||
|
TVariable* TParseContextBase::getEditableVariable(const char* name)
|
||||||
|
{
|
||||||
|
bool builtIn;
|
||||||
|
TSymbol* symbol = symbolTable.find(name, &builtIn);
|
||||||
|
|
||||||
|
assert(symbol != nullptr);
|
||||||
|
if (symbol == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (builtIn)
|
||||||
|
makeEditable(symbol);
|
||||||
|
|
||||||
|
return symbol->getAsVariable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the best matching function for 'call' from 'candidateList'.
|
||||||
|
//
|
||||||
|
// Assumptions
|
||||||
|
//
|
||||||
|
// There is no exact match, so a selection algorithm needs to run. That is, the
|
||||||
|
// language-specific handler should check for exact match first, to
|
||||||
|
// decide what to do, before calling this selector.
|
||||||
|
//
|
||||||
|
// Input
|
||||||
|
//
|
||||||
|
// * list of candidate signatures to select from
|
||||||
|
// * the call
|
||||||
|
// * a predicate function convertible(from, to) that says whether or not type
|
||||||
|
// 'from' can implicitly convert to type 'to' (it includes the case of what
|
||||||
|
// the calling language would consider a matching type with no conversion
|
||||||
|
// needed)
|
||||||
|
// * a predicate function better(from1, from2, to1, to2) that says whether or
|
||||||
|
// not a conversion from <-> to2 is considered better than a conversion
|
||||||
|
// from <-> to1 (both in and out directions need testing, as declared by the
|
||||||
|
// formal parameter)
|
||||||
|
//
|
||||||
|
// Output
|
||||||
|
//
|
||||||
|
// * best matching candidate (or none, if no viable candidates found)
|
||||||
|
// * whether there was a tie for the best match (ambiguous overload selection,
|
||||||
|
// caller's choice for how to report)
|
||||||
|
//
|
||||||
|
const TFunction* TParseContextBase::selectFunction(
|
||||||
|
const TVector<const TFunction*> candidateList,
|
||||||
|
const TFunction& call,
|
||||||
|
std::function<bool(const TType& from, const TType& to, TOperator op, int arg)> convertible,
|
||||||
|
std::function<bool(const TType& from, const TType& to1, const TType& to2)> better,
|
||||||
|
/* output */ bool& tie)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Operation
|
||||||
|
//
|
||||||
|
// 1. Prune the input list of candidates down to a list of viable candidates,
|
||||||
|
// where each viable candidate has
|
||||||
|
//
|
||||||
|
// * at least as many parameters as there are calling arguments, with any
|
||||||
|
// remaining parameters being optional or having default values
|
||||||
|
// * each parameter is true under convertible(A, B), where A is the calling
|
||||||
|
// type for in and B is the formal type, and in addition, for out B is the
|
||||||
|
// calling type and A is the formal type
|
||||||
|
//
|
||||||
|
// 2. If there are no viable candidates, return with no match.
|
||||||
|
//
|
||||||
|
// 3. If there is only one viable candidate, it is the best match.
|
||||||
|
//
|
||||||
|
// 4. If there are multiple viable candidates, select the first viable candidate
|
||||||
|
// as the incumbent. Compare the incumbent to the next viable candidate, and if
|
||||||
|
// that candidate is better (bullets below), make it the incumbent. Repeat, with
|
||||||
|
// a linear walk through the viable candidate list. The final incumbent will be
|
||||||
|
// returned as the best match. A viable candidate is better than the incumbent if
|
||||||
|
//
|
||||||
|
// * it has a function argument with a better(...) conversion than the incumbent,
|
||||||
|
// for all directions needed by in and out
|
||||||
|
// * the incumbent has no argument with a better(...) conversion then the
|
||||||
|
// candidate, for either in or out (as needed)
|
||||||
|
//
|
||||||
|
// 5. Check for ambiguity by comparing the best match against all other viable
|
||||||
|
// candidates. If any other viable candidate has a function argument with a
|
||||||
|
// better(...) conversion than the best candidate (for either in or out
|
||||||
|
// directions), return that there was a tie for best.
|
||||||
|
//
|
||||||
|
|
||||||
|
tie = false;
|
||||||
|
|
||||||
|
// 1. prune to viable...
|
||||||
|
TVector<const TFunction*> viableCandidates;
|
||||||
|
for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
|
||||||
|
const TFunction& candidate = *(*it);
|
||||||
|
|
||||||
|
// to even be a potential match, number of arguments must be >= the number of
|
||||||
|
// fixed (non-default) parameters, and <= the total (including parameter with defaults).
|
||||||
|
if (call.getParamCount() < candidate.getFixedParamCount() ||
|
||||||
|
call.getParamCount() > candidate.getParamCount())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// see if arguments are convertible
|
||||||
|
bool viable = true;
|
||||||
|
|
||||||
|
// The call can have fewer parameters than the candidate, if some have defaults.
|
||||||
|
const int paramCount = std::min(call.getParamCount(), candidate.getParamCount());
|
||||||
|
for (int param = 0; param < paramCount; ++param) {
|
||||||
|
if (candidate[param].type->getQualifier().isParamInput()) {
|
||||||
|
if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) {
|
||||||
|
viable = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (candidate[param].type->getQualifier().isParamOutput()) {
|
||||||
|
if (! convertible(*candidate[param].type, *call[param].type, candidate.getBuiltInOp(), param)) {
|
||||||
|
viable = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viable)
|
||||||
|
viableCandidates.push_back(&candidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. none viable...
|
||||||
|
if (viableCandidates.size() == 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// 3. only one viable...
|
||||||
|
if (viableCandidates.size() == 1)
|
||||||
|
return viableCandidates.front();
|
||||||
|
|
||||||
|
// 4. find best...
|
||||||
|
const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
|
||||||
|
// is call -> can2 better than call -> can1 for any parameter
|
||||||
|
bool hasBetterParam = false;
|
||||||
|
for (int param = 0; param < call.getParamCount(); ++param) {
|
||||||
|
if (better(*call[param].type, *can1[param].type, *can2[param].type)) {
|
||||||
|
hasBetterParam = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasBetterParam;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
|
||||||
|
// is call -> can2 equivalent to call -> can1 for all the call parameters?
|
||||||
|
for (int param = 0; param < call.getParamCount(); ++param) {
|
||||||
|
if (better(*call[param].type, *can1[param].type, *can2[param].type) ||
|
||||||
|
better(*call[param].type, *can2[param].type, *can1[param].type))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const TFunction* incumbent = viableCandidates.front();
|
||||||
|
for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
|
||||||
|
const TFunction& candidate = *(*it);
|
||||||
|
if (betterParam(*incumbent, candidate) && ! betterParam(candidate, *incumbent))
|
||||||
|
incumbent = &candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. ambiguity...
|
||||||
|
for (auto it = viableCandidates.begin(); it != viableCandidates.end(); ++it) {
|
||||||
|
if (incumbent == *it)
|
||||||
|
continue;
|
||||||
|
const TFunction& candidate = *(*it);
|
||||||
|
|
||||||
|
// In the case of default parameters, it may have an identical initial set, which is
|
||||||
|
// also ambiguous
|
||||||
|
if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
|
||||||
|
tie = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return incumbent;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Look at a '.' field selector string and change it into numerical selectors
|
||||||
|
// for a vector or scalar.
|
||||||
|
//
|
||||||
|
// Always return some form of swizzle, so the result is always usable.
|
||||||
|
//
|
||||||
|
void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TString& compString, int vecSize,
|
||||||
|
TSwizzleSelectors<TVectorSelector>& selector)
|
||||||
|
{
|
||||||
|
// Too long?
|
||||||
|
if (compString.size() > MaxSwizzleSelectors)
|
||||||
|
error(loc, "vector swizzle too long", compString.c_str(), "");
|
||||||
|
|
||||||
|
// Use this to test that all swizzle characters are from the same swizzle-namespace-set
|
||||||
|
enum {
|
||||||
|
exyzw,
|
||||||
|
ergba,
|
||||||
|
estpq,
|
||||||
|
} fieldSet[MaxSwizzleSelectors];
|
||||||
|
|
||||||
|
// Decode the swizzle string.
|
||||||
|
int size = std::min(MaxSwizzleSelectors, (int)compString.size());
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
switch (compString[i]) {
|
||||||
|
case 'x':
|
||||||
|
selector.push_back(0);
|
||||||
|
fieldSet[i] = exyzw;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
selector.push_back(0);
|
||||||
|
fieldSet[i] = ergba;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
selector.push_back(0);
|
||||||
|
fieldSet[i] = estpq;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'y':
|
||||||
|
selector.push_back(1);
|
||||||
|
fieldSet[i] = exyzw;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
selector.push_back(1);
|
||||||
|
fieldSet[i] = ergba;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
selector.push_back(1);
|
||||||
|
fieldSet[i] = estpq;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
selector.push_back(2);
|
||||||
|
fieldSet[i] = exyzw;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
selector.push_back(2);
|
||||||
|
fieldSet[i] = ergba;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
selector.push_back(2);
|
||||||
|
fieldSet[i] = estpq;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
selector.push_back(3);
|
||||||
|
fieldSet[i] = exyzw;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
selector.push_back(3);
|
||||||
|
fieldSet[i] = ergba;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
selector.push_back(3);
|
||||||
|
fieldSet[i] = estpq;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error(loc, "unknown swizzle selection", compString.c_str(), "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional error checking.
|
||||||
|
for (int i = 0; i < selector.size(); ++i) {
|
||||||
|
if (selector[i] >= vecSize) {
|
||||||
|
error(loc, "vector swizzle selection out of range", compString.c_str(), "");
|
||||||
|
selector.resize(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0 && fieldSet[i] != fieldSet[i-1]) {
|
||||||
|
error(loc, "vector swizzle selectors not from the same set", compString.c_str(), "");
|
||||||
|
selector.resize(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure it is valid.
|
||||||
|
if (selector.size() == 0)
|
||||||
|
selector.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the passed-in variable information become a member of the
|
||||||
|
// global uniform block. If this doesn't exist yet, make it.
|
||||||
|
//
|
||||||
|
void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList)
|
||||||
|
{
|
||||||
|
// Make the global block, if not yet made.
|
||||||
|
if (globalUniformBlock == nullptr) {
|
||||||
|
TQualifier blockQualifier;
|
||||||
|
blockQualifier.clear();
|
||||||
|
blockQualifier.storage = EvqUniform;
|
||||||
|
TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier);
|
||||||
|
setUniformBlockDefaults(blockType);
|
||||||
|
globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true);
|
||||||
|
firstNewMember = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update with binding and set
|
||||||
|
globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
|
||||||
|
globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
|
||||||
|
|
||||||
|
// Add the requested member as a member to the global block.
|
||||||
|
TType* type = new TType;
|
||||||
|
type->shallowCopy(memberType);
|
||||||
|
type->setFieldName(memberName);
|
||||||
|
if (typeList)
|
||||||
|
type->setStruct(typeList);
|
||||||
|
TTypeLoc typeLoc = {type, loc};
|
||||||
|
globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
|
||||||
|
|
||||||
|
// Insert into the symbol table.
|
||||||
|
if (firstNewMember == 0) {
|
||||||
|
// This is the first request; we need a normal symbol table insert
|
||||||
|
if (symbolTable.insert(*globalUniformBlock))
|
||||||
|
trackLinkage(*globalUniformBlock);
|
||||||
|
else
|
||||||
|
error(loc, "failed to insert the global constant buffer", "uniform", "");
|
||||||
|
} else {
|
||||||
|
// This is a follow-on request; we need to amend the first insert
|
||||||
|
symbolTable.amend(*globalUniformBlock, firstNewMember);
|
||||||
|
}
|
||||||
|
|
||||||
|
++firstNewMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TParseContextBase::finish()
|
||||||
|
{
|
||||||
|
if (parsingBuiltins)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Transfer the linkage symbols to AST nodes, preserving order.
|
||||||
|
TIntermAggregate* linkage = new TIntermAggregate;
|
||||||
|
for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)
|
||||||
|
intermediate.addSymbolLinkageNode(linkage, **i);
|
||||||
|
intermediate.addSymbolLinkageNodes(linkage, getLanguage(), symbolTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace glslang
|
2219
Externals/glslang/glslang/MachineIndependent/ParseHelper.cpp
vendored
Normal file → Executable file
2219
Externals/glslang/glslang/MachineIndependent/ParseHelper.cpp
vendored
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -44,14 +44,15 @@
|
||||||
#ifndef _PARSER_HELPER_INCLUDED_
|
#ifndef _PARSER_HELPER_INCLUDED_
|
||||||
#define _PARSER_HELPER_INCLUDED_
|
#define _PARSER_HELPER_INCLUDED_
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "parseVersions.h"
|
#include "parseVersions.h"
|
||||||
#include "../Include/ShHandle.h"
|
#include "../Include/ShHandle.h"
|
||||||
#include "SymbolTable.h"
|
#include "SymbolTable.h"
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
#include "Scan.h"
|
#include "Scan.h"
|
||||||
#include <functional>
|
#include "attribute.h"
|
||||||
|
|
||||||
#include <cstdarg>
|
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
@ -73,18 +74,41 @@ typedef std::set<int> TIdSetType;
|
||||||
//
|
//
|
||||||
class TParseContextBase : public TParseVersions {
|
class TParseContextBase : public TParseVersions {
|
||||||
public:
|
public:
|
||||||
TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, int version,
|
TParseContextBase(TSymbolTable& symbolTable, TIntermediate& interm, bool parsingBuiltins, int version,
|
||||||
EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
|
EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
|
||||||
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages)
|
TInfoSink& infoSink, bool forwardCompatible, EShMessages messages,
|
||||||
|
const TString* entryPoint = nullptr)
|
||||||
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
: TParseVersions(interm, version, profile, spvVersion, language, infoSink, forwardCompatible, messages),
|
||||||
symbolTable(symbolTable), tokensBeforeEOF(false),
|
scopeMangler("::"),
|
||||||
linkage(nullptr), scanContext(nullptr), ppContext(nullptr) { }
|
symbolTable(symbolTable),
|
||||||
|
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||||
|
postEntryPointReturn(false),
|
||||||
|
contextPragma(true, false),
|
||||||
|
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
||||||
|
limits(resources.limits),
|
||||||
|
globalUniformBlock(nullptr),
|
||||||
|
globalUniformBinding(TQualifier::layoutBindingEnd),
|
||||||
|
globalUniformSet(TQualifier::layoutSetEnd)
|
||||||
|
{
|
||||||
|
if (entryPoint != nullptr)
|
||||||
|
sourceEntryPointName = *entryPoint;
|
||||||
|
}
|
||||||
virtual ~TParseContextBase() { }
|
virtual ~TParseContextBase() { }
|
||||||
|
|
||||||
|
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
virtual void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...);
|
||||||
|
|
||||||
virtual void setLimits(const TBuiltInResource&) = 0;
|
virtual void setLimits(const TBuiltInResource&) = 0;
|
||||||
|
|
||||||
|
void checkIndex(const TSourceLoc&, const TType&, int& index);
|
||||||
|
|
||||||
EShLanguage getLanguage() const { return language; }
|
EShLanguage getLanguage() const { return language; }
|
||||||
TIntermAggregate*& getLinkage() { return linkage; }
|
|
||||||
void setScanContext(TScanContext* c) { scanContext = c; }
|
void setScanContext(TScanContext* c) { scanContext = c; }
|
||||||
TScanContext* getScanContext() const { return scanContext; }
|
TScanContext* getScanContext() const { return scanContext; }
|
||||||
void setPpContext(TPpContext* c) { ppContext = c; }
|
void setPpContext(TPpContext* c) { ppContext = c; }
|
||||||
|
@ -124,16 +148,51 @@ public:
|
||||||
extensionCallback(line, extension, behavior);
|
extensionCallback(line, extension, behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||||
|
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
||||||
|
|
||||||
|
// Potentially rename shader entry point function
|
||||||
|
void renameShaderFunction(TString*& name) const
|
||||||
|
{
|
||||||
|
// Replace the entry point name given in the shader with the real entry point name,
|
||||||
|
// if there is a substitution.
|
||||||
|
if (name != nullptr && *name == sourceEntryPointName && intermediate.getEntryPointName().size() > 0)
|
||||||
|
name = NewPoolTString(intermediate.getEntryPointName().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||||
|
virtual void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
||||||
|
|
||||||
|
const char* const scopeMangler;
|
||||||
|
|
||||||
|
// Basic parsing state, easily accessible to the grammar
|
||||||
|
|
||||||
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile
|
||||||
bool tokensBeforeEOF;
|
int statementNestingLevel; // 0 if outside all flow control or compound statements
|
||||||
|
int loopNestingLevel; // 0 if outside all loops
|
||||||
|
int structNestingLevel; // 0 if outside blocks and structures
|
||||||
|
int controlFlowNestingLevel; // 0 if outside all flow control
|
||||||
|
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
||||||
|
bool functionReturnsValue; // true if a non-void function has a return
|
||||||
|
// if inside a function, true if the function is the entry point and this is after a return statement
|
||||||
|
bool postEntryPointReturn;
|
||||||
|
// case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
||||||
|
TList<TIntermSequence*> switchSequenceStack;
|
||||||
|
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
||||||
|
TList<int> switchLevel;
|
||||||
|
struct TPragma contextPragma;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TParseContextBase(TParseContextBase&);
|
TParseContextBase(TParseContextBase&);
|
||||||
TParseContextBase& operator=(TParseContextBase&);
|
TParseContextBase& operator=(TParseContextBase&);
|
||||||
|
|
||||||
TIntermAggregate* linkage; // aggregate node of objects the linker may need, if not referenced by the rest of the AST
|
const bool parsingBuiltins; // true if parsing built-in symbols/functions
|
||||||
|
TVector<TSymbol*> linkageSymbols; // will be transferred to 'linkage', after all editing is done, order preserving
|
||||||
TScanContext* scanContext;
|
TScanContext* scanContext;
|
||||||
TPpContext* ppContext;
|
TPpContext* ppContext;
|
||||||
|
TBuiltInResource resources;
|
||||||
|
TLimits& limits;
|
||||||
|
TString sourceEntryPointName;
|
||||||
|
|
||||||
// These, if set, will be called when a line, pragma ... is preprocessed.
|
// These, if set, will be called when a line, pragma ... is preprocessed.
|
||||||
// They will be called with any parameters to the original directive.
|
// They will be called with any parameters to the original directive.
|
||||||
|
@ -142,6 +201,66 @@ protected:
|
||||||
std::function<void(int, int, const char*)> versionCallback;
|
std::function<void(int, int, const char*)> versionCallback;
|
||||||
std::function<void(int, const char*, const char*)> extensionCallback;
|
std::function<void(int, const char*, const char*)> extensionCallback;
|
||||||
std::function<void(int, const char*)> errorCallback;
|
std::function<void(int, const char*)> errorCallback;
|
||||||
|
|
||||||
|
// see implementation for detail
|
||||||
|
const TFunction* selectFunction(const TVector<const TFunction*>, const TFunction&,
|
||||||
|
std::function<bool(const TType&, const TType&, TOperator, int arg)>,
|
||||||
|
std::function<bool(const TType&, const TType&, const TType&)>,
|
||||||
|
/* output */ bool& tie);
|
||||||
|
|
||||||
|
virtual void parseSwizzleSelector(const TSourceLoc&, const TString&, int size,
|
||||||
|
TSwizzleSelectors<TVectorSelector>&);
|
||||||
|
|
||||||
|
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||||
|
TVariable* globalUniformBlock; // the actual block, inserted into the symbol table
|
||||||
|
unsigned int globalUniformBinding; // the block's binding number
|
||||||
|
unsigned int globalUniformSet; // the block's set number
|
||||||
|
int firstNewMember; // the index of the first member not yet inserted into the symbol table
|
||||||
|
// override this to set the language-specific name
|
||||||
|
virtual const char* getGlobalUniformBlockName() const { return ""; }
|
||||||
|
virtual void setUniformBlockDefaults(TType&) const { }
|
||||||
|
virtual void finalizeGlobalUniformBlockLayout(TVariable&) { }
|
||||||
|
virtual void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, TPrefixType prefix,
|
||||||
|
va_list args);
|
||||||
|
virtual void trackLinkage(TSymbol& symbol);
|
||||||
|
virtual void makeEditable(TSymbol*&);
|
||||||
|
virtual TVariable* getEditableVariable(const char* name);
|
||||||
|
virtual void finish();
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Manage the state for when to respect precision qualifiers and when to warn about
|
||||||
|
// the defaults being different than might be expected.
|
||||||
|
//
|
||||||
|
class TPrecisionManager {
|
||||||
|
public:
|
||||||
|
TPrecisionManager() : obey(false), warn(false), explicitIntDefault(false), explicitFloatDefault(false){ }
|
||||||
|
virtual ~TPrecisionManager() {}
|
||||||
|
|
||||||
|
void respectPrecisionQualifiers() { obey = true; }
|
||||||
|
bool respectingPrecisionQualifiers() const { return obey; }
|
||||||
|
bool shouldWarnAboutDefaults() const { return warn; }
|
||||||
|
void defaultWarningGiven() { warn = false; }
|
||||||
|
void warnAboutDefaults() { warn = true; }
|
||||||
|
void explicitIntDefaultSeen()
|
||||||
|
{
|
||||||
|
explicitIntDefault = true;
|
||||||
|
if (explicitFloatDefault)
|
||||||
|
warn = false;
|
||||||
|
}
|
||||||
|
void explicitFloatDefaultSeen()
|
||||||
|
{
|
||||||
|
explicitFloatDefault = true;
|
||||||
|
if (explicitIntDefault)
|
||||||
|
warn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool obey; // respect precision qualifiers
|
||||||
|
bool warn; // need to give a warning about the defaults
|
||||||
|
bool explicitIntDefault; // user set the default for int/uint
|
||||||
|
bool explicitFloatDefault; // user set the default for float
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -152,36 +271,29 @@ protected:
|
||||||
class TParseContext : public TParseContextBase {
|
class TParseContext : public TParseContextBase {
|
||||||
public:
|
public:
|
||||||
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&,
|
TParseContext(TSymbolTable&, TIntermediate&, bool parsingBuiltins, int version, EProfile, const SpvVersion& spvVersion, EShLanguage, TInfoSink&,
|
||||||
bool forwardCompatible = false, EShMessages messages = EShMsgDefault);
|
bool forwardCompatible = false, EShMessages messages = EShMsgDefault,
|
||||||
|
const TString* entryPoint = nullptr);
|
||||||
virtual ~TParseContext();
|
virtual ~TParseContext();
|
||||||
|
|
||||||
void setLimits(const TBuiltInResource&);
|
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); };
|
||||||
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false);
|
void setPrecisionDefaults();
|
||||||
|
|
||||||
|
void setLimits(const TBuiltInResource&) override;
|
||||||
|
bool parseShaderStrings(TPpContext&, TInputScanner& input, bool versionWillBeError = false) override;
|
||||||
void parserError(const char* s); // for bison's yyerror
|
void parserError(const char* s); // for bison's yyerror
|
||||||
|
|
||||||
void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
|
||||||
const char* szExtraInfoFormat, ...);
|
|
||||||
void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
|
||||||
const char* szExtraInfoFormat, ...);
|
|
||||||
void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
|
|
||||||
const char* szExtraInfoFormat, ...);
|
|
||||||
void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
|
||||||
const char* szExtraInfoFormat, ...);
|
|
||||||
|
|
||||||
void reservedErrorCheck(const TSourceLoc&, const TString&);
|
void reservedErrorCheck(const TSourceLoc&, const TString&);
|
||||||
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op);
|
void reservedPpErrorCheck(const TSourceLoc&, const char* name, const char* op) override;
|
||||||
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment);
|
bool lineContinuationCheck(const TSourceLoc&, bool endOfComment) override;
|
||||||
bool lineDirectiveShouldSetNextLine() const;
|
bool lineDirectiveShouldSetNextLine() const override;
|
||||||
bool builtInName(const TString&);
|
bool builtInName(const TString&);
|
||||||
|
|
||||||
void handlePragma(const TSourceLoc&, const TVector<TString>&);
|
void handlePragma(const TSourceLoc&, const TVector<TString>&) override;
|
||||||
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
|
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
|
||||||
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
||||||
void checkIndex(const TSourceLoc&, const TType&, int& index);
|
|
||||||
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
||||||
|
|
||||||
void makeEditable(TSymbol*&);
|
void makeEditable(TSymbol*&) override;
|
||||||
TVariable* getEditableVariable(const char* name);
|
|
||||||
bool isIoResizeArray(const TType&) const;
|
bool isIoResizeArray(const TType&) const;
|
||||||
void fixIoArraySize(const TSourceLoc&, TType&);
|
void fixIoArraySize(const TSourceLoc&, TType&);
|
||||||
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
|
@ -197,6 +309,8 @@ public:
|
||||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||||
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
|
TIntermTyped* handleBuiltInFunctionCall(TSourceLoc, TIntermNode* arguments, const TFunction& function);
|
||||||
|
void computeBuiltinPrecisions(TIntermTyped&, const TFunction&);
|
||||||
TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
|
TIntermNode* handleReturnValue(const TSourceLoc&, TIntermTyped*);
|
||||||
void checkLocation(const TSourceLoc&, TOperator);
|
void checkLocation(const TSourceLoc&, TOperator);
|
||||||
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
|
||||||
|
@ -204,15 +318,18 @@ public:
|
||||||
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;
|
||||||
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
|
||||||
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
|
void nonOpBuiltInCheck(const TSourceLoc&, const TFunction&, TIntermAggregate&);
|
||||||
|
void userFunctionCallCheck(const TSourceLoc&, TIntermAggregate&);
|
||||||
|
void samplerConstructorLocationCheck(const TSourceLoc&, const char* token, TIntermNode*);
|
||||||
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
||||||
|
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
|
||||||
|
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
||||||
|
|
||||||
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
|
|
||||||
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
||||||
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
|
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
void variableCheck(TIntermTyped*& nodePtr);
|
void variableCheck(TIntermTyped*& nodePtr);
|
||||||
bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
bool lValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
|
||||||
void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*);
|
void rValueErrorCheck(const TSourceLoc&, const char* op, TIntermTyped*) override;
|
||||||
void constantValueCheck(TIntermTyped* node, const char* token);
|
void constantValueCheck(TIntermTyped* node, const char* token);
|
||||||
void integerCheck(const TIntermTyped* node, const char* token);
|
void integerCheck(const TIntermTyped* node, const char* token);
|
||||||
void globalCheck(const TSourceLoc&, const char* token);
|
void globalCheck(const TSourceLoc&, const char* token);
|
||||||
|
@ -223,17 +340,15 @@ public:
|
||||||
bool arrayError(const TSourceLoc&, const TType&);
|
bool arrayError(const TSourceLoc&, const TType&);
|
||||||
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
||||||
void structArrayCheck(const TSourceLoc&, const TType& structure);
|
void structArrayCheck(const TSourceLoc&, const TType& structure);
|
||||||
void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
|
void arraySizesCheck(const TSourceLoc&, const TQualifier&, TArraySizes*, const TIntermTyped* initializer, bool lastMember);
|
||||||
void arrayOfArrayVersionCheck(const TSourceLoc&);
|
void arrayOfArrayVersionCheck(const TSourceLoc&, const TArraySizes*);
|
||||||
void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
|
|
||||||
void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
|
|
||||||
void arrayDimMerge(TType& type, const TArraySizes* sizes);
|
|
||||||
bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
|
bool voidErrorCheck(const TSourceLoc&, const TString&, TBasicType);
|
||||||
void boolCheck(const TSourceLoc&, const TIntermTyped*);
|
void boolCheck(const TSourceLoc&, const TIntermTyped*);
|
||||||
void boolCheck(const TSourceLoc&, const TPublicType&);
|
void boolCheck(const TSourceLoc&, const TPublicType&);
|
||||||
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
void samplerCheck(const TSourceLoc&, const TType&, const TString& identifier, TIntermTyped* initializer);
|
||||||
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void atomicUintCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
void transparentCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
|
void memberQualifierCheck(glslang::TPublicType&);
|
||||||
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
|
void globalQualifierFixCheck(const TSourceLoc&, TQualifier&);
|
||||||
void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
|
void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&);
|
||||||
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType);
|
||||||
|
@ -244,9 +359,9 @@ public:
|
||||||
void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&);
|
void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&);
|
||||||
void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type);
|
void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type);
|
||||||
bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
|
bool containsFieldWithBasicType(const TType& type ,TBasicType basicType);
|
||||||
TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration);
|
TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&);
|
||||||
void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
|
void redeclareBuiltinBlock(const TSourceLoc&, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
|
||||||
void paramCheckFix(const TSourceLoc&, const TStorageQualifier&, TType& type);
|
void paramCheckFixStorage(const TSourceLoc&, const TStorageQualifier&, TType& type);
|
||||||
void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
|
void paramCheckFix(const TSourceLoc&, const TQualifier&, TType& type);
|
||||||
void nestedBlockCheck(const TSourceLoc&);
|
void nestedBlockCheck(const TSourceLoc&);
|
||||||
void nestedStructCheck(const TSourceLoc&);
|
void nestedStructCheck(const TSourceLoc&);
|
||||||
|
@ -265,6 +380,7 @@ public:
|
||||||
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
|
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
|
||||||
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
||||||
void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
|
void layoutObjectCheck(const TSourceLoc&, const TSymbol&);
|
||||||
|
void layoutMemberLocationArrayCheck(const TSourceLoc&, bool memberWithLocation, TArraySizes* arraySizes);
|
||||||
void layoutTypeCheck(const TSourceLoc&, const TType&);
|
void layoutTypeCheck(const TSourceLoc&, const TType&);
|
||||||
void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
|
void layoutQualifierCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
||||||
|
@ -274,9 +390,10 @@ public:
|
||||||
const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
const TFunction* findFunctionExact(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
||||||
const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
const TFunction* findFunction120(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
||||||
const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
||||||
|
const TFunction* findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn);
|
||||||
void declareTypeDefaults(const TSourceLoc&, const TPublicType&);
|
void declareTypeDefaults(const TSourceLoc&, const TPublicType&);
|
||||||
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||||
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&, TOperator);
|
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
|
||||||
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
||||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
||||||
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
||||||
|
@ -292,21 +409,29 @@ public:
|
||||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
||||||
|
|
||||||
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
TAttributeType attributeFromName(const TString& name) const;
|
||||||
|
TAttributes* makeAttributes(const TString& identifier) const;
|
||||||
|
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
|
||||||
|
TAttributes* mergeAttributes(TAttributes*, TAttributes*) const;
|
||||||
|
|
||||||
|
// Determine selection control from attributes
|
||||||
|
void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
|
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
|
|
||||||
|
// Determine loop control from attributes
|
||||||
|
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
||||||
void inheritGlobalDefaults(TQualifier& dst) const;
|
void inheritGlobalDefaults(TQualifier& dst) const;
|
||||||
TVariable* makeInternalVariable(const char* name, const TType&) const;
|
TVariable* makeInternalVariable(const char* name, const TType&) const;
|
||||||
TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool& newDeclaration);
|
TVariable* declareNonArray(const TSourceLoc&, const TString& identifier, const TType&);
|
||||||
void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration);
|
void declareArray(const TSourceLoc&, const TString& identifier, const TType&, TSymbol*&);
|
||||||
|
void checkRuntimeSizable(const TSourceLoc&, const TIntermTyped&);
|
||||||
|
bool isRuntimeLength(const TIntermTyped&) const;
|
||||||
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
||||||
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
||||||
TOperator mapTypeToConstructorOp(const TType&) const;
|
void finish() override;
|
||||||
void finalErrorCheck();
|
|
||||||
void outputMessage(const TSourceLoc&, const char* szReason, const char* szToken,
|
|
||||||
const char* szExtraInfoFormat, TPrefixType prefix,
|
|
||||||
va_list args);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//
|
//
|
||||||
|
@ -314,17 +439,7 @@ public:
|
||||||
//
|
//
|
||||||
|
|
||||||
// Current state of parsing
|
// Current state of parsing
|
||||||
struct TPragma contextPragma;
|
|
||||||
int loopNestingLevel; // 0 if outside all loops
|
|
||||||
int structNestingLevel; // 0 if outside blocks and structures
|
|
||||||
int controlFlowNestingLevel; // 0 if outside all flow control
|
|
||||||
int statementNestingLevel; // 0 if outside all flow control or compound statements
|
|
||||||
TList<TIntermSequence*> switchSequenceStack; // case, node, case, case, node, ...; ensure only one node between cases; stack of them for nesting
|
|
||||||
TList<int> switchLevel; // the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
|
||||||
bool inMain; // if inside a function, true if the function is main
|
bool inMain; // if inside a function, true if the function is main
|
||||||
bool postMainReturn; // if inside a function, true if the function is main and this is after a return statement
|
|
||||||
const TType* currentFunctionType; // the return type of the function that's currently being parsed
|
|
||||||
bool functionReturnsValue; // true if a non-void function has a return
|
|
||||||
const TString* blockName;
|
const TString* blockName;
|
||||||
TQualifier currentBlockQualifier;
|
TQualifier currentBlockQualifier;
|
||||||
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
TPrecisionQualifier defaultPrecision[EbtNumTypes];
|
||||||
|
@ -335,10 +450,9 @@ protected:
|
||||||
TParseContext(TParseContext&);
|
TParseContext(TParseContext&);
|
||||||
TParseContext& operator=(TParseContext&);
|
TParseContext& operator=(TParseContext&);
|
||||||
|
|
||||||
const bool parsingBuiltins; // true if parsing built-in symbols/functions
|
|
||||||
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2 * 2 * 2)); // see computeSamplerTypeIndex()
|
static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2 * 2 * 2)); // see computeSamplerTypeIndex()
|
||||||
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
|
TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
|
||||||
bool afterEOF;
|
TPrecisionManager precisionManager;
|
||||||
TQualifier globalBufferDefaults;
|
TQualifier globalBufferDefaults;
|
||||||
TQualifier globalUniformDefaults;
|
TQualifier globalUniformDefaults;
|
||||||
TQualifier globalInputDefaults;
|
TQualifier globalInputDefaults;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
|
@ -40,35 +40,22 @@
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
// Process-wide TLS index
|
||||||
OS_TLSIndex PoolIndex;
|
OS_TLSIndex PoolIndex;
|
||||||
|
|
||||||
void InitializeMemoryPools()
|
// Return the thread-specific current pool.
|
||||||
|
TPoolAllocator& GetThreadPoolAllocator()
|
||||||
{
|
{
|
||||||
TThreadMemoryPools* pools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
return *static_cast<TPoolAllocator*>(OS_GetTLSValue(PoolIndex));
|
||||||
if (pools)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TPoolAllocator *threadPoolAllocator = new TPoolAllocator();
|
|
||||||
|
|
||||||
TThreadMemoryPools* threadData = new TThreadMemoryPools();
|
|
||||||
|
|
||||||
threadData->threadPoolAllocator = threadPoolAllocator;
|
|
||||||
|
|
||||||
OS_SetTLSValue(PoolIndex, threadData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreeGlobalPools()
|
// Set the thread-specific current pool.
|
||||||
|
void SetThreadPoolAllocator(TPoolAllocator* poolAllocator)
|
||||||
{
|
{
|
||||||
// Release the allocated memory for this thread.
|
OS_SetTLSValue(PoolIndex, poolAllocator);
|
||||||
TThreadMemoryPools* globalPools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
|
||||||
if (! globalPools)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GetThreadPoolAllocator().popAll();
|
|
||||||
delete &GetThreadPoolAllocator();
|
|
||||||
delete globalPools;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process-wide set up of the TLS pool storage.
|
||||||
bool InitializePoolIndex()
|
bool InitializePoolIndex()
|
||||||
{
|
{
|
||||||
// Allocate a TLS index.
|
// Allocate a TLS index.
|
||||||
|
@ -78,26 +65,6 @@ bool InitializePoolIndex()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FreePoolIndex()
|
|
||||||
{
|
|
||||||
// Release the TLS index.
|
|
||||||
OS_FreeTLSIndex(PoolIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
TPoolAllocator& GetThreadPoolAllocator()
|
|
||||||
{
|
|
||||||
TThreadMemoryPools* threadData = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
|
||||||
|
|
||||||
return *threadData->threadPoolAllocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetThreadPoolAllocator(TPoolAllocator& poolAllocator)
|
|
||||||
{
|
|
||||||
TThreadMemoryPools* threadData = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
|
||||||
|
|
||||||
threadData->threadPoolAllocator = &poolAllocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Implement the functionality of the TPoolAllocator class, which
|
// Implement the functionality of the TPoolAllocator class, which
|
||||||
// is documented in PoolAlloc.h.
|
// is documented in PoolAlloc.h.
|
||||||
|
@ -105,8 +72,8 @@ void SetThreadPoolAllocator(TPoolAllocator& poolAllocator)
|
||||||
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
|
TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
|
||||||
pageSize(growthIncrement),
|
pageSize(growthIncrement),
|
||||||
alignment(allocationAlignment),
|
alignment(allocationAlignment),
|
||||||
freeList(0),
|
freeList(nullptr),
|
||||||
inUseList(0),
|
inUseList(nullptr),
|
||||||
numCalls(0)
|
numCalls(0)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -206,7 +173,6 @@ void TAllocation::checkGuardBlock(unsigned char*, unsigned char, const char*) co
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TPoolAllocator::push()
|
void TPoolAllocator::push()
|
||||||
{
|
{
|
||||||
tAllocState state = { currentPageOffset, inUseList };
|
tAllocState state = { currentPageOffset, inUseList };
|
||||||
|
@ -235,13 +201,16 @@ void TPoolAllocator::pop()
|
||||||
currentPageOffset = stack.back().offset;
|
currentPageOffset = stack.back().offset;
|
||||||
|
|
||||||
while (inUseList != page) {
|
while (inUseList != page) {
|
||||||
// invoke destructor to free allocation list
|
|
||||||
inUseList->~tHeader();
|
|
||||||
|
|
||||||
tHeader* nextInUse = inUseList->nextPage;
|
tHeader* nextInUse = inUseList->nextPage;
|
||||||
if (inUseList->pageCount > 1)
|
size_t pageCount = inUseList->pageCount;
|
||||||
|
|
||||||
|
// This technically ends the lifetime of the header as C++ object,
|
||||||
|
// but we will still control the memory and reuse it.
|
||||||
|
inUseList->~tHeader(); // currently, just a debug allocation checker
|
||||||
|
|
||||||
|
if (pageCount > 1) {
|
||||||
delete [] reinterpret_cast<char*>(inUseList);
|
delete [] reinterpret_cast<char*>(inUseList);
|
||||||
else {
|
} else {
|
||||||
inUseList->nextPage = freeList;
|
inUseList->nextPage = freeList;
|
||||||
freeList = inUseList;
|
freeList = inUseList;
|
||||||
}
|
}
|
||||||
|
@ -334,7 +303,6 @@ void* TPoolAllocator::allocate(size_t numBytes)
|
||||||
return initializeAllocation(inUseList, ret, numBytes);
|
return initializeAllocation(inUseList, ret, numBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check all allocations in a list for damage by calling check on each.
|
// Check all allocations in a list for damage by calling check on each.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "../Include/intermediate.h"
|
#include "../Include/intermediate.h"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,20 +18,22 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
void RemoveAllTreeNodes(TIntermNode*);
|
void RemoveAllTreeNodes(TIntermNode*);
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,31 +21,32 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// GLSL scanning, leveraging the scanning done by the preprocessor.
|
// GLSL scanning, leveraging the scanning done by the preprocessor.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "../Include/Types.h"
|
#include "../Include/Types.h"
|
||||||
#include "SymbolTable.h"
|
#include "SymbolTable.h"
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
|
#include "attribute.h"
|
||||||
#include "glslang_tab.cpp.h"
|
#include "glslang_tab.cpp.h"
|
||||||
#include "ScanContext.h"
|
#include "ScanContext.h"
|
||||||
#include "Scan.h"
|
#include "Scan.h"
|
||||||
|
@ -339,6 +341,7 @@ void TScanContext::fillInKeywordMap()
|
||||||
|
|
||||||
(*KeywordMap)["const"] = CONST;
|
(*KeywordMap)["const"] = CONST;
|
||||||
(*KeywordMap)["uniform"] = UNIFORM;
|
(*KeywordMap)["uniform"] = UNIFORM;
|
||||||
|
(*KeywordMap)["nonuniformEXT"] = NONUNIFORM;
|
||||||
(*KeywordMap)["in"] = IN;
|
(*KeywordMap)["in"] = IN;
|
||||||
(*KeywordMap)["out"] = OUT;
|
(*KeywordMap)["out"] = OUT;
|
||||||
(*KeywordMap)["inout"] = INOUT;
|
(*KeywordMap)["inout"] = INOUT;
|
||||||
|
@ -463,6 +466,84 @@ void TScanContext::fillInKeywordMap()
|
||||||
(*KeywordMap)["u64vec3"] = U64VEC3;
|
(*KeywordMap)["u64vec3"] = U64VEC3;
|
||||||
(*KeywordMap)["u64vec4"] = U64VEC4;
|
(*KeywordMap)["u64vec4"] = U64VEC4;
|
||||||
|
|
||||||
|
// GL_KHX_shader_explicit_arithmetic_types
|
||||||
|
(*KeywordMap)["int8_t"] = INT8_T;
|
||||||
|
(*KeywordMap)["i8vec2"] = I8VEC2;
|
||||||
|
(*KeywordMap)["i8vec3"] = I8VEC3;
|
||||||
|
(*KeywordMap)["i8vec4"] = I8VEC4;
|
||||||
|
(*KeywordMap)["uint8_t"] = UINT8_T;
|
||||||
|
(*KeywordMap)["u8vec2"] = U8VEC2;
|
||||||
|
(*KeywordMap)["u8vec3"] = U8VEC3;
|
||||||
|
(*KeywordMap)["u8vec4"] = U8VEC4;
|
||||||
|
|
||||||
|
(*KeywordMap)["int16_t"] = INT16_T;
|
||||||
|
(*KeywordMap)["i16vec2"] = I16VEC2;
|
||||||
|
(*KeywordMap)["i16vec3"] = I16VEC3;
|
||||||
|
(*KeywordMap)["i16vec4"] = I16VEC4;
|
||||||
|
(*KeywordMap)["uint16_t"] = UINT16_T;
|
||||||
|
(*KeywordMap)["u16vec2"] = U16VEC2;
|
||||||
|
(*KeywordMap)["u16vec3"] = U16VEC3;
|
||||||
|
(*KeywordMap)["u16vec4"] = U16VEC4;
|
||||||
|
|
||||||
|
(*KeywordMap)["int32_t"] = INT32_T;
|
||||||
|
(*KeywordMap)["i32vec2"] = I32VEC2;
|
||||||
|
(*KeywordMap)["i32vec3"] = I32VEC3;
|
||||||
|
(*KeywordMap)["i32vec4"] = I32VEC4;
|
||||||
|
(*KeywordMap)["uint32_t"] = UINT32_T;
|
||||||
|
(*KeywordMap)["u32vec2"] = U32VEC2;
|
||||||
|
(*KeywordMap)["u32vec3"] = U32VEC3;
|
||||||
|
(*KeywordMap)["u32vec4"] = U32VEC4;
|
||||||
|
|
||||||
|
(*KeywordMap)["float16_t"] = FLOAT16_T;
|
||||||
|
(*KeywordMap)["f16vec2"] = F16VEC2;
|
||||||
|
(*KeywordMap)["f16vec3"] = F16VEC3;
|
||||||
|
(*KeywordMap)["f16vec4"] = F16VEC4;
|
||||||
|
(*KeywordMap)["f16mat2"] = F16MAT2;
|
||||||
|
(*KeywordMap)["f16mat3"] = F16MAT3;
|
||||||
|
(*KeywordMap)["f16mat4"] = F16MAT4;
|
||||||
|
(*KeywordMap)["f16mat2x2"] = F16MAT2X2;
|
||||||
|
(*KeywordMap)["f16mat2x3"] = F16MAT2X3;
|
||||||
|
(*KeywordMap)["f16mat2x4"] = F16MAT2X4;
|
||||||
|
(*KeywordMap)["f16mat3x2"] = F16MAT3X2;
|
||||||
|
(*KeywordMap)["f16mat3x3"] = F16MAT3X3;
|
||||||
|
(*KeywordMap)["f16mat3x4"] = F16MAT3X4;
|
||||||
|
(*KeywordMap)["f16mat4x2"] = F16MAT4X2;
|
||||||
|
(*KeywordMap)["f16mat4x3"] = F16MAT4X3;
|
||||||
|
(*KeywordMap)["f16mat4x4"] = F16MAT4X4;
|
||||||
|
|
||||||
|
(*KeywordMap)["float32_t"] = FLOAT32_T;
|
||||||
|
(*KeywordMap)["f32vec2"] = F32VEC2;
|
||||||
|
(*KeywordMap)["f32vec3"] = F32VEC3;
|
||||||
|
(*KeywordMap)["f32vec4"] = F32VEC4;
|
||||||
|
(*KeywordMap)["f32mat2"] = F32MAT2;
|
||||||
|
(*KeywordMap)["f32mat3"] = F32MAT3;
|
||||||
|
(*KeywordMap)["f32mat4"] = F32MAT4;
|
||||||
|
(*KeywordMap)["f32mat2x2"] = F32MAT2X2;
|
||||||
|
(*KeywordMap)["f32mat2x3"] = F32MAT2X3;
|
||||||
|
(*KeywordMap)["f32mat2x4"] = F32MAT2X4;
|
||||||
|
(*KeywordMap)["f32mat3x2"] = F32MAT3X2;
|
||||||
|
(*KeywordMap)["f32mat3x3"] = F32MAT3X3;
|
||||||
|
(*KeywordMap)["f32mat3x4"] = F32MAT3X4;
|
||||||
|
(*KeywordMap)["f32mat4x2"] = F32MAT4X2;
|
||||||
|
(*KeywordMap)["f32mat4x3"] = F32MAT4X3;
|
||||||
|
(*KeywordMap)["f32mat4x4"] = F32MAT4X4;
|
||||||
|
(*KeywordMap)["float64_t"] = FLOAT64_T;
|
||||||
|
(*KeywordMap)["f64vec2"] = F64VEC2;
|
||||||
|
(*KeywordMap)["f64vec3"] = F64VEC3;
|
||||||
|
(*KeywordMap)["f64vec4"] = F64VEC4;
|
||||||
|
(*KeywordMap)["f64mat2"] = F64MAT2;
|
||||||
|
(*KeywordMap)["f64mat3"] = F64MAT3;
|
||||||
|
(*KeywordMap)["f64mat4"] = F64MAT4;
|
||||||
|
(*KeywordMap)["f64mat2x2"] = F64MAT2X2;
|
||||||
|
(*KeywordMap)["f64mat2x3"] = F64MAT2X3;
|
||||||
|
(*KeywordMap)["f64mat2x4"] = F64MAT2X4;
|
||||||
|
(*KeywordMap)["f64mat3x2"] = F64MAT3X2;
|
||||||
|
(*KeywordMap)["f64mat3x3"] = F64MAT3X3;
|
||||||
|
(*KeywordMap)["f64mat3x4"] = F64MAT3X4;
|
||||||
|
(*KeywordMap)["f64mat4x2"] = F64MAT4X2;
|
||||||
|
(*KeywordMap)["f64mat4x3"] = F64MAT4X3;
|
||||||
|
(*KeywordMap)["f64mat4x4"] = F64MAT4X4;
|
||||||
|
|
||||||
(*KeywordMap)["sampler2D"] = SAMPLER2D;
|
(*KeywordMap)["sampler2D"] = SAMPLER2D;
|
||||||
(*KeywordMap)["samplerCube"] = SAMPLERCUBE;
|
(*KeywordMap)["samplerCube"] = SAMPLERCUBE;
|
||||||
(*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY;
|
(*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY;
|
||||||
|
@ -550,9 +631,60 @@ void TScanContext::fillInKeywordMap()
|
||||||
(*KeywordMap)["usubpassInput"] = USUBPASSINPUT;
|
(*KeywordMap)["usubpassInput"] = USUBPASSINPUT;
|
||||||
(*KeywordMap)["usubpassInputMS"] = USUBPASSINPUTMS;
|
(*KeywordMap)["usubpassInputMS"] = USUBPASSINPUTMS;
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
(*KeywordMap)["f16sampler1D"] = F16SAMPLER1D;
|
||||||
|
(*KeywordMap)["f16sampler2D"] = F16SAMPLER2D;
|
||||||
|
(*KeywordMap)["f16sampler3D"] = F16SAMPLER3D;
|
||||||
|
(*KeywordMap)["f16sampler2DRect"] = F16SAMPLER2DRECT;
|
||||||
|
(*KeywordMap)["f16samplerCube"] = F16SAMPLERCUBE;
|
||||||
|
(*KeywordMap)["f16sampler1DArray"] = F16SAMPLER1DARRAY;
|
||||||
|
(*KeywordMap)["f16sampler2DArray"] = F16SAMPLER2DARRAY;
|
||||||
|
(*KeywordMap)["f16samplerCubeArray"] = F16SAMPLERCUBEARRAY;
|
||||||
|
(*KeywordMap)["f16samplerBuffer"] = F16SAMPLERBUFFER;
|
||||||
|
(*KeywordMap)["f16sampler2DMS"] = F16SAMPLER2DMS;
|
||||||
|
(*KeywordMap)["f16sampler2DMSArray"] = F16SAMPLER2DMSARRAY;
|
||||||
|
(*KeywordMap)["f16sampler1DShadow"] = F16SAMPLER1DSHADOW;
|
||||||
|
(*KeywordMap)["f16sampler2DShadow"] = F16SAMPLER2DSHADOW;
|
||||||
|
(*KeywordMap)["f16sampler2DRectShadow"] = F16SAMPLER2DRECTSHADOW;
|
||||||
|
(*KeywordMap)["f16samplerCubeShadow"] = F16SAMPLERCUBESHADOW;
|
||||||
|
(*KeywordMap)["f16sampler1DArrayShadow"] = F16SAMPLER1DARRAYSHADOW;
|
||||||
|
(*KeywordMap)["f16sampler2DArrayShadow"] = F16SAMPLER2DARRAYSHADOW;
|
||||||
|
(*KeywordMap)["f16samplerCubeArrayShadow"] = F16SAMPLERCUBEARRAYSHADOW;
|
||||||
|
|
||||||
|
(*KeywordMap)["f16image1D"] = F16IMAGE1D;
|
||||||
|
(*KeywordMap)["f16image2D"] = F16IMAGE2D;
|
||||||
|
(*KeywordMap)["f16image3D"] = F16IMAGE3D;
|
||||||
|
(*KeywordMap)["f16image2DRect"] = F16IMAGE2DRECT;
|
||||||
|
(*KeywordMap)["f16imageCube"] = F16IMAGECUBE;
|
||||||
|
(*KeywordMap)["f16image1DArray"] = F16IMAGE1DARRAY;
|
||||||
|
(*KeywordMap)["f16image2DArray"] = F16IMAGE2DARRAY;
|
||||||
|
(*KeywordMap)["f16imageCubeArray"] = F16IMAGECUBEARRAY;
|
||||||
|
(*KeywordMap)["f16imageBuffer"] = F16IMAGEBUFFER;
|
||||||
|
(*KeywordMap)["f16image2DMS"] = F16IMAGE2DMS;
|
||||||
|
(*KeywordMap)["f16image2DMSArray"] = F16IMAGE2DMSARRAY;
|
||||||
|
|
||||||
|
(*KeywordMap)["f16texture1D"] = F16TEXTURE1D;
|
||||||
|
(*KeywordMap)["f16texture2D"] = F16TEXTURE2D;
|
||||||
|
(*KeywordMap)["f16texture3D"] = F16TEXTURE3D;
|
||||||
|
(*KeywordMap)["f16texture2DRect"] = F16TEXTURE2DRECT;
|
||||||
|
(*KeywordMap)["f16textureCube"] = F16TEXTURECUBE;
|
||||||
|
(*KeywordMap)["f16texture1DArray"] = F16TEXTURE1DARRAY;
|
||||||
|
(*KeywordMap)["f16texture2DArray"] = F16TEXTURE2DARRAY;
|
||||||
|
(*KeywordMap)["f16textureCubeArray"] = F16TEXTURECUBEARRAY;
|
||||||
|
(*KeywordMap)["f16textureBuffer"] = F16TEXTUREBUFFER;
|
||||||
|
(*KeywordMap)["f16texture2DMS"] = F16TEXTURE2DMS;
|
||||||
|
(*KeywordMap)["f16texture2DMSArray"] = F16TEXTURE2DMSARRAY;
|
||||||
|
|
||||||
|
(*KeywordMap)["f16subpassInput"] = F16SUBPASSINPUT;
|
||||||
|
(*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS;
|
||||||
|
#endif
|
||||||
|
|
||||||
(*KeywordMap)["noperspective"] = NOPERSPECTIVE;
|
(*KeywordMap)["noperspective"] = NOPERSPECTIVE;
|
||||||
(*KeywordMap)["smooth"] = SMOOTH;
|
(*KeywordMap)["smooth"] = SMOOTH;
|
||||||
(*KeywordMap)["flat"] = FLAT;
|
(*KeywordMap)["flat"] = FLAT;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
(*KeywordMap)["__explicitInterpAMD"] = __EXPLICITINTERPAMD;
|
||||||
|
#endif
|
||||||
(*KeywordMap)["centroid"] = CENTROID;
|
(*KeywordMap)["centroid"] = CENTROID;
|
||||||
(*KeywordMap)["precise"] = PRECISE;
|
(*KeywordMap)["precise"] = PRECISE;
|
||||||
(*KeywordMap)["invariant"] = INVARIANT;
|
(*KeywordMap)["invariant"] = INVARIANT;
|
||||||
|
@ -609,18 +741,21 @@ void TScanContext::deleteKeywordMap()
|
||||||
ReservedSet = nullptr;
|
ReservedSet = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by yylex to get the next token.
|
||||||
|
// Returning 0 implies end of input.
|
||||||
int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
parserToken = &token;
|
parserToken = &token;
|
||||||
TPpToken ppToken;
|
TPpToken ppToken;
|
||||||
tokenText = pp->tokenize(&ppToken);
|
int token = pp->tokenize(ppToken);
|
||||||
if (tokenText == nullptr)
|
if (token == EndOfInput)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
tokenText = ppToken.name;
|
||||||
loc = ppToken.loc;
|
loc = ppToken.loc;
|
||||||
parserToken->sType.lex.loc = loc;
|
parserToken->sType.lex.loc = loc;
|
||||||
switch (ppToken.token) {
|
switch (token) {
|
||||||
case ';': afterType = false; return SEMICOLON;
|
case ';': afterType = false; return SEMICOLON;
|
||||||
case ',': afterType = false; return COMMA;
|
case ',': afterType = false; return COMMA;
|
||||||
case ':': return COLON;
|
case ':': return COLON;
|
||||||
|
@ -649,11 +784,11 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
||||||
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PpAtomAdd: return ADD_ASSIGN;
|
case PPAtomAddAssign: return ADD_ASSIGN;
|
||||||
case PpAtomSub: return SUB_ASSIGN;
|
case PPAtomSubAssign: return SUB_ASSIGN;
|
||||||
case PpAtomMul: return MUL_ASSIGN;
|
case PPAtomMulAssign: return MUL_ASSIGN;
|
||||||
case PpAtomDiv: return DIV_ASSIGN;
|
case PPAtomDivAssign: return DIV_ASSIGN;
|
||||||
case PpAtomMod: return MOD_ASSIGN;
|
case PPAtomModAssign: return MOD_ASSIGN;
|
||||||
|
|
||||||
case PpAtomRight: return RIGHT_OP;
|
case PpAtomRight: return RIGHT_OP;
|
||||||
case PpAtomLeft: return LEFT_OP;
|
case PpAtomLeft: return LEFT_OP;
|
||||||
|
@ -676,12 +811,19 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
||||||
case PpAtomDecrement: return DEC_OP;
|
case PpAtomDecrement: return DEC_OP;
|
||||||
case PpAtomIncrement: return INC_OP;
|
case PpAtomIncrement: return INC_OP;
|
||||||
|
|
||||||
|
case PpAtomColonColon:
|
||||||
|
parseContext.error(loc, "not supported", "::", "");
|
||||||
|
break;
|
||||||
|
|
||||||
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
|
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
|
||||||
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
|
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
|
||||||
|
case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT;
|
||||||
|
case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT;
|
||||||
case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT;
|
case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT;
|
||||||
case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
|
case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
|
||||||
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
|
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
|
||||||
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
|
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
|
||||||
|
case PpAtomConstFloat16: parserToken->sType.lex.d = ppToken.dval; return FLOAT16CONSTANT;
|
||||||
case PpAtomIdentifier:
|
case PpAtomIdentifier:
|
||||||
{
|
{
|
||||||
int token = tokenizeIdentifier();
|
int token = tokenizeIdentifier();
|
||||||
|
@ -693,7 +835,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
char buf[2];
|
char buf[2];
|
||||||
buf[0] = (char)ppToken.token;
|
buf[0] = (char)token;
|
||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
parseContext.error(loc, "unexpected token", buf, "");
|
parseContext.error(loc, "unexpected token", buf, "");
|
||||||
break;
|
break;
|
||||||
|
@ -732,6 +874,12 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case CASE:
|
case CASE:
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
|
case NONUNIFORM:
|
||||||
|
if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
|
||||||
|
return keyword;
|
||||||
|
else
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
case SWITCH:
|
case SWITCH:
|
||||||
case DEFAULT:
|
case DEFAULT:
|
||||||
if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
|
if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
|
||||||
|
@ -796,7 +944,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case VOLATILE:
|
case VOLATILE:
|
||||||
if (parseContext.profile == EEsProfile && parseContext.version >= 310)
|
if (parseContext.profile == EEsProfile && parseContext.version >= 310)
|
||||||
return keyword;
|
return keyword;
|
||||||
if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile || (parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
|
if (! parseContext.symbolTable.atBuiltInLevel() && (parseContext.profile == EEsProfile ||
|
||||||
|
(parseContext.version < 420 && ! parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
|
||||||
reservedWord();
|
reservedWord();
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
|
@ -819,14 +968,17 @@ int TScanContext::tokenizeIdentifier()
|
||||||
|
|
||||||
case PATCH:
|
case PATCH:
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
(parseContext.profile == EEsProfile && parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) ||
|
(parseContext.profile == EEsProfile &&
|
||||||
|
(parseContext.version >= 320 ||
|
||||||
|
parseContext.extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader))) ||
|
||||||
(parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader)))
|
(parseContext.profile != EEsProfile && parseContext.extensionTurnedOn(E_GL_ARB_tessellation_shader)))
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
return es30ReservedFromGLSL(400);
|
return es30ReservedFromGLSL(400);
|
||||||
|
|
||||||
case SAMPLE:
|
case SAMPLE:
|
||||||
if (parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation))
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionsTurnedOn(1, &E_GL_OES_shader_multisample_interpolation))
|
||||||
return keyword;
|
return keyword;
|
||||||
return es30ReservedFromGLSL(400);
|
return es30ReservedFromGLSL(400);
|
||||||
|
|
||||||
|
@ -880,7 +1032,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case IIMAGEBUFFER:
|
case IIMAGEBUFFER:
|
||||||
case UIMAGEBUFFER:
|
case UIMAGEBUFFER:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
|
||||||
return keyword;
|
return keyword;
|
||||||
return firstGenerationImage(false);
|
return firstGenerationImage(false);
|
||||||
|
|
||||||
|
@ -903,7 +1056,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case IIMAGECUBEARRAY:
|
case IIMAGECUBEARRAY:
|
||||||
case UIMAGECUBEARRAY:
|
case UIMAGECUBEARRAY:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
|
||||||
return keyword;
|
return keyword;
|
||||||
return secondGenerationImage();
|
return secondGenerationImage();
|
||||||
|
|
||||||
|
@ -933,16 +1087,149 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case U64VEC2:
|
case U64VEC2:
|
||||||
case U64VEC3:
|
case U64VEC3:
|
||||||
case U64VEC4:
|
case U64VEC4:
|
||||||
if (parseContext.profile != EEsProfile && parseContext.version >= 450)
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
(parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
||||||
|
(parseContext.extensionTurnedOn(E_GL_ARB_gpu_shader_int64) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int64))))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
|
||||||
|
case INT8_T:
|
||||||
|
case UINT8_T:
|
||||||
|
case I8VEC2:
|
||||||
|
case I8VEC3:
|
||||||
|
case I8VEC4:
|
||||||
|
case U8VEC2:
|
||||||
|
case U8VEC3:
|
||||||
|
case U8VEC4:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int8)) &&
|
||||||
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
|
case INT16_T:
|
||||||
|
case UINT16_T:
|
||||||
|
case I16VEC2:
|
||||||
|
case I16VEC3:
|
||||||
|
case I16VEC4:
|
||||||
|
case U16VEC2:
|
||||||
|
case U16VEC3:
|
||||||
|
case U16VEC4:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
(parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
||||||
|
(
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
|
||||||
|
#endif
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int16))))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
case INT32_T:
|
||||||
|
case UINT32_T:
|
||||||
|
case I32VEC2:
|
||||||
|
case I32VEC3:
|
||||||
|
case I32VEC4:
|
||||||
|
case U32VEC2:
|
||||||
|
case U32VEC3:
|
||||||
|
case U32VEC4:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int32)) &&
|
||||||
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
case FLOAT32_T:
|
||||||
|
case F32VEC2:
|
||||||
|
case F32VEC3:
|
||||||
|
case F32VEC4:
|
||||||
|
case F32MAT2:
|
||||||
|
case F32MAT3:
|
||||||
|
case F32MAT4:
|
||||||
|
case F32MAT2X2:
|
||||||
|
case F32MAT2X3:
|
||||||
|
case F32MAT2X4:
|
||||||
|
case F32MAT3X2:
|
||||||
|
case F32MAT3X3:
|
||||||
|
case F32MAT3X4:
|
||||||
|
case F32MAT4X2:
|
||||||
|
case F32MAT4X3:
|
||||||
|
case F32MAT4X4:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float32)) &&
|
||||||
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
|
case FLOAT64_T:
|
||||||
|
case F64VEC2:
|
||||||
|
case F64VEC3:
|
||||||
|
case F64VEC4:
|
||||||
|
case F64MAT2:
|
||||||
|
case F64MAT3:
|
||||||
|
case F64MAT4:
|
||||||
|
case F64MAT2X2:
|
||||||
|
case F64MAT2X3:
|
||||||
|
case F64MAT2X4:
|
||||||
|
case F64MAT3X2:
|
||||||
|
case F64MAT3X3:
|
||||||
|
case F64MAT3X4:
|
||||||
|
case F64MAT4X2:
|
||||||
|
case F64MAT4X3:
|
||||||
|
case F64MAT4X4:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float64)) &&
|
||||||
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
|
case FLOAT16_T:
|
||||||
|
case F16VEC2:
|
||||||
|
case F16VEC3:
|
||||||
|
case F16VEC4:
|
||||||
|
case F16MAT2:
|
||||||
|
case F16MAT3:
|
||||||
|
case F16MAT4:
|
||||||
|
case F16MAT2X2:
|
||||||
|
case F16MAT2X3:
|
||||||
|
case F16MAT2X4:
|
||||||
|
case F16MAT3X2:
|
||||||
|
case F16MAT3X3:
|
||||||
|
case F16MAT3X4:
|
||||||
|
case F16MAT4X2:
|
||||||
|
case F16MAT4X3:
|
||||||
|
case F16MAT4X4:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
(parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
||||||
|
(
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
|
||||||
|
#endif
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16))))
|
||||||
|
return keyword;
|
||||||
|
|
||||||
|
return identifierOrType();
|
||||||
|
|
||||||
case SAMPLERCUBEARRAY:
|
case SAMPLERCUBEARRAY:
|
||||||
case SAMPLERCUBEARRAYSHADOW:
|
case SAMPLERCUBEARRAYSHADOW:
|
||||||
case ISAMPLERCUBEARRAY:
|
case ISAMPLERCUBEARRAY:
|
||||||
case USAMPLERCUBEARRAY:
|
case USAMPLERCUBEARRAY:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
|
||||||
return keyword;
|
return keyword;
|
||||||
if (parseContext.profile == EEsProfile || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array)))
|
if (parseContext.profile == EEsProfile || (parseContext.version < 400 && ! parseContext.extensionTurnedOn(E_GL_ARB_texture_cube_map_array)))
|
||||||
reservedWord();
|
reservedWord();
|
||||||
|
@ -981,14 +1268,16 @@ int TScanContext::tokenizeIdentifier()
|
||||||
|
|
||||||
case SAMPLERBUFFER:
|
case SAMPLERBUFFER:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
|
||||||
return keyword;
|
return keyword;
|
||||||
return es30ReservedFromGLSL(130);
|
return es30ReservedFromGLSL(130);
|
||||||
|
|
||||||
case ISAMPLERBUFFER:
|
case ISAMPLERBUFFER:
|
||||||
case USAMPLERBUFFER:
|
case USAMPLERBUFFER:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionsTurnedOn(Num_AEP_texture_buffer, AEP_texture_buffer))
|
||||||
return keyword;
|
return keyword;
|
||||||
return es30ReservedFromGLSL(140);
|
return es30ReservedFromGLSL(140);
|
||||||
|
|
||||||
|
@ -1004,7 +1293,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case ISAMPLER2DMSARRAY:
|
case ISAMPLER2DMSARRAY:
|
||||||
case USAMPLER2DMSARRAY:
|
case USAMPLER2DMSARRAY:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array))
|
if ((parseContext.profile == EEsProfile && parseContext.version >= 320) ||
|
||||||
|
parseContext.extensionsTurnedOn(1, &E_GL_OES_texture_storage_multisample_2d_array))
|
||||||
return keyword;
|
return keyword;
|
||||||
return es30ReservedFromGLSL(150);
|
return es30ReservedFromGLSL(150);
|
||||||
|
|
||||||
|
@ -1018,15 +1308,17 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case SAMPLER3D:
|
case SAMPLER3D:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.profile == EEsProfile && parseContext.version < 300) {
|
if (parseContext.profile == EEsProfile && parseContext.version < 300) {
|
||||||
if (! parseContext.extensionTurnedOn(E_GL_OES_texture_3D))
|
if (!parseContext.extensionTurnedOn(E_GL_OES_texture_3D))
|
||||||
reservedWord();
|
reservedWord();
|
||||||
}
|
}
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
case SAMPLER2DSHADOW:
|
case SAMPLER2DSHADOW:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.profile == EEsProfile && parseContext.version < 300)
|
if (parseContext.profile == EEsProfile && parseContext.version < 300) {
|
||||||
|
if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers))
|
||||||
reservedWord();
|
reservedWord();
|
||||||
|
}
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
case SAMPLER2DRECT:
|
case SAMPLER2DRECT:
|
||||||
|
@ -1053,7 +1345,9 @@ int TScanContext::tokenizeIdentifier()
|
||||||
|
|
||||||
case SAMPLEREXTERNALOES:
|
case SAMPLEREXTERNALOES:
|
||||||
afterType = true;
|
afterType = true;
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() || parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external))
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external) ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_OES_EGL_image_external_essl3))
|
||||||
return keyword;
|
return keyword;
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
|
||||||
|
@ -1092,7 +1386,7 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case TEXTURE1DARRAY:
|
case TEXTURE1DARRAY:
|
||||||
case SAMPLER:
|
case SAMPLER:
|
||||||
case SAMPLERSHADOW:
|
case SAMPLERSHADOW:
|
||||||
if (parseContext.spvVersion.vulkan >= 100)
|
if (parseContext.spvVersion.vulkan > 0)
|
||||||
return keyword;
|
return keyword;
|
||||||
else
|
else
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
@ -1103,12 +1397,71 @@ int TScanContext::tokenizeIdentifier()
|
||||||
case ISUBPASSINPUTMS:
|
case ISUBPASSINPUTMS:
|
||||||
case USUBPASSINPUT:
|
case USUBPASSINPUT:
|
||||||
case USUBPASSINPUTMS:
|
case USUBPASSINPUTMS:
|
||||||
if (parseContext.spvVersion.vulkan >= 100)
|
if (parseContext.spvVersion.vulkan > 0)
|
||||||
return keyword;
|
return keyword;
|
||||||
else
|
else
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case F16SAMPLER1D:
|
||||||
|
case F16SAMPLER2D:
|
||||||
|
case F16SAMPLER3D:
|
||||||
|
case F16SAMPLER2DRECT:
|
||||||
|
case F16SAMPLERCUBE:
|
||||||
|
case F16SAMPLER1DARRAY:
|
||||||
|
case F16SAMPLER2DARRAY:
|
||||||
|
case F16SAMPLERCUBEARRAY:
|
||||||
|
case F16SAMPLERBUFFER:
|
||||||
|
case F16SAMPLER2DMS:
|
||||||
|
case F16SAMPLER2DMSARRAY:
|
||||||
|
case F16SAMPLER1DSHADOW:
|
||||||
|
case F16SAMPLER2DSHADOW:
|
||||||
|
case F16SAMPLER1DARRAYSHADOW:
|
||||||
|
case F16SAMPLER2DARRAYSHADOW:
|
||||||
|
case F16SAMPLER2DRECTSHADOW:
|
||||||
|
case F16SAMPLERCUBESHADOW:
|
||||||
|
case F16SAMPLERCUBEARRAYSHADOW:
|
||||||
|
|
||||||
|
case F16IMAGE1D:
|
||||||
|
case F16IMAGE2D:
|
||||||
|
case F16IMAGE3D:
|
||||||
|
case F16IMAGE2DRECT:
|
||||||
|
case F16IMAGECUBE:
|
||||||
|
case F16IMAGE1DARRAY:
|
||||||
|
case F16IMAGE2DARRAY:
|
||||||
|
case F16IMAGECUBEARRAY:
|
||||||
|
case F16IMAGEBUFFER:
|
||||||
|
case F16IMAGE2DMS:
|
||||||
|
case F16IMAGE2DMSARRAY:
|
||||||
|
|
||||||
|
case F16TEXTURE1D:
|
||||||
|
case F16TEXTURE2D:
|
||||||
|
case F16TEXTURE3D:
|
||||||
|
case F16TEXTURE2DRECT:
|
||||||
|
case F16TEXTURECUBE:
|
||||||
|
case F16TEXTURE1DARRAY:
|
||||||
|
case F16TEXTURE2DARRAY:
|
||||||
|
case F16TEXTURECUBEARRAY:
|
||||||
|
case F16TEXTUREBUFFER:
|
||||||
|
case F16TEXTURE2DMS:
|
||||||
|
case F16TEXTURE2DMSARRAY:
|
||||||
|
|
||||||
|
case F16SUBPASSINPUT:
|
||||||
|
case F16SUBPASSINPUTMS:
|
||||||
|
afterType = true;
|
||||||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
|
(parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float_fetch) &&
|
||||||
|
parseContext.profile != EEsProfile && parseContext.version >= 450))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
#endif
|
||||||
|
|
||||||
case NOPERSPECTIVE:
|
case NOPERSPECTIVE:
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (parseContext.profile == EEsProfile && parseContext.version >= 300 &&
|
||||||
|
parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation))
|
||||||
|
return keyword;
|
||||||
|
#endif
|
||||||
return es30ReservedFromGLSL(130);
|
return es30ReservedFromGLSL(130);
|
||||||
|
|
||||||
case SMOOTH:
|
case SMOOTH:
|
||||||
|
@ -1117,6 +1470,14 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return identifierOrType();
|
return identifierOrType();
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case __EXPLICITINTERPAMD:
|
||||||
|
if (parseContext.profile != EEsProfile && parseContext.version >= 450 &&
|
||||||
|
parseContext.extensionTurnedOn(E_GL_AMD_shader_explicit_vertex_parameter))
|
||||||
|
return keyword;
|
||||||
|
return identifierOrType();
|
||||||
|
#endif
|
||||||
|
|
||||||
case FLAT:
|
case FLAT:
|
||||||
if (parseContext.profile == EEsProfile && parseContext.version < 300)
|
if (parseContext.profile == EEsProfile && parseContext.version < 300)
|
||||||
reservedWord();
|
reservedWord();
|
||||||
|
@ -1130,7 +1491,8 @@ int TScanContext::tokenizeIdentifier()
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
case PRECISE:
|
case PRECISE:
|
||||||
if ((parseContext.profile == EEsProfile && parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5)) ||
|
if ((parseContext.profile == EEsProfile &&
|
||||||
|
(parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) ||
|
||||||
(parseContext.profile != EEsProfile && parseContext.version >= 400))
|
(parseContext.profile != EEsProfile && parseContext.version >= 400))
|
||||||
return keyword;
|
return keyword;
|
||||||
if (parseContext.profile == EEsProfile && parseContext.version == 310) {
|
if (parseContext.profile == EEsProfile && parseContext.version == 310) {
|
||||||
|
@ -1293,7 +1655,8 @@ int TScanContext::dMat()
|
||||||
int TScanContext::firstGenerationImage(bool inEs310)
|
int TScanContext::firstGenerationImage(bool inEs310)
|
||||||
{
|
{
|
||||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||||
(parseContext.profile != EEsProfile && (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) ||
|
(parseContext.profile != EEsProfile && (parseContext.version >= 420 ||
|
||||||
|
parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))) ||
|
||||||
(inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310))
|
(inEs310 && parseContext.profile == EEsProfile && parseContext.version >= 310))
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
#ifndef _GLSLANG_SCAN_INCLUDED_
|
#ifndef _GLSLANG_SCAN_INCLUDED_
|
||||||
#define _GLSLANG_SCAN_INCLUDED_
|
#define _GLSLANG_SCAN_INCLUDED_
|
||||||
|
@ -51,25 +51,24 @@ const int EndOfInput = -1;
|
||||||
//
|
//
|
||||||
class TInputScanner {
|
class TInputScanner {
|
||||||
public:
|
public:
|
||||||
TInputScanner(int n, const char* const s[], size_t L[], const char* const* names = nullptr, int b = 0, int f = 0, bool single = false) :
|
TInputScanner(int n, const char* const s[], size_t L[], const char* const* names = nullptr,
|
||||||
|
int b = 0, int f = 0, bool single = false) :
|
||||||
numSources(n),
|
numSources(n),
|
||||||
sources(reinterpret_cast<const unsigned char* const *>(s)), // up to this point, common usage is "char*", but now we need positive 8-bit characters
|
// up to this point, common usage is "char*", but now we need positive 8-bit characters
|
||||||
lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f), singleLogical(single), endOfFileReached(false)
|
sources(reinterpret_cast<const unsigned char* const *>(s)),
|
||||||
|
lengths(L), currentSource(0), currentChar(0), stringBias(b), finale(f), singleLogical(single),
|
||||||
|
endOfFileReached(false)
|
||||||
{
|
{
|
||||||
loc = new TSourceLoc[numSources];
|
loc = new TSourceLoc[numSources];
|
||||||
for (int i = 0; i < numSources; ++i) {
|
for (int i = 0; i < numSources; ++i) {
|
||||||
loc[i].init();
|
loc[i].init(i - stringBias);
|
||||||
}
|
}
|
||||||
if (names != nullptr) {
|
if (names != nullptr) {
|
||||||
for (int i = 0; i < numSources; ++i)
|
for (int i = 0; i < numSources; ++i)
|
||||||
loc[i].name = names[i];
|
loc[i].name = names[i];
|
||||||
}
|
}
|
||||||
loc[currentSource].string = -stringBias;
|
|
||||||
loc[currentSource].line = 1;
|
loc[currentSource].line = 1;
|
||||||
loc[currentSource].column = 0;
|
logicalSourceLoc.init(1);
|
||||||
logicalSourceLoc.string = 0;
|
|
||||||
logicalSourceLoc.line = 1;
|
|
||||||
logicalSourceLoc.column = 0;
|
|
||||||
logicalSourceLoc.name = loc[0].name;
|
logicalSourceLoc.name = loc[0].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +203,8 @@ public:
|
||||||
currentSource = numSources;
|
currentSource = numSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool atEndOfInput() const { return endOfFileReached; }
|
||||||
|
|
||||||
const TSourceLoc& getSourceLoc() const
|
const TSourceLoc& getSourceLoc() const
|
||||||
{
|
{
|
||||||
if (singleLogical) {
|
if (singleLogical) {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -38,6 +38,8 @@
|
||||||
// sits between the preprocessor scanner and parser.
|
// sits between the preprocessor scanner and parser.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,22 +21,22 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Symbol table for parsing. Most functionaliy and main ideas
|
// Symbol table for parsing. Most functionality and main ideas
|
||||||
// are documented in the header file.
|
// are documented in the header file.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ namespace glslang {
|
||||||
//
|
//
|
||||||
// Recursively generate mangled names.
|
// Recursively generate mangled names.
|
||||||
//
|
//
|
||||||
void TType::buildMangledName(TString& mangledName)
|
void TType::buildMangledName(TString& mangledName) const
|
||||||
{
|
{
|
||||||
if (isMatrix())
|
if (isMatrix())
|
||||||
mangledName += 'm';
|
mangledName += 'm';
|
||||||
|
@ -60,14 +61,22 @@ void TType::buildMangledName(TString& mangledName)
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
case EbtFloat: mangledName += 'f'; break;
|
case EbtFloat: mangledName += 'f'; break;
|
||||||
case EbtDouble: mangledName += 'd'; break;
|
case EbtDouble: mangledName += 'd'; break;
|
||||||
|
case EbtFloat16: mangledName += "f16"; break;
|
||||||
case EbtInt: mangledName += 'i'; break;
|
case EbtInt: mangledName += 'i'; break;
|
||||||
case EbtUint: mangledName += 'u'; break;
|
case EbtUint: mangledName += 'u'; break;
|
||||||
|
case EbtInt8: mangledName += "i8"; break;
|
||||||
|
case EbtUint8: mangledName += "u8"; break;
|
||||||
|
case EbtInt16: mangledName += "i16"; break;
|
||||||
|
case EbtUint16: mangledName += "u16"; break;
|
||||||
case EbtInt64: mangledName += "i64"; break;
|
case EbtInt64: mangledName += "i64"; break;
|
||||||
case EbtUint64: mangledName += "u64"; break;
|
case EbtUint64: mangledName += "u64"; break;
|
||||||
case EbtBool: mangledName += 'b'; break;
|
case EbtBool: mangledName += 'b'; break;
|
||||||
case EbtAtomicUint: mangledName += "au"; break;
|
case EbtAtomicUint: mangledName += "au"; break;
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
switch (sampler.type) {
|
switch (sampler.type) {
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EbtFloat16: mangledName += "f16"; break;
|
||||||
|
#endif
|
||||||
case EbtInt: mangledName += "i"; break;
|
case EbtInt: mangledName += "i"; break;
|
||||||
case EbtUint: mangledName += "u"; break;
|
case EbtUint: mangledName += "u"; break;
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
|
@ -96,11 +105,32 @@ void TType::buildMangledName(TString& mangledName)
|
||||||
case EsdSubpass: mangledName += "P"; break;
|
case EsdSubpass: mangledName += "P"; break;
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sampler.hasReturnStruct()) {
|
||||||
|
// Name mangle for sampler return struct uses struct table index.
|
||||||
|
mangledName += "-tx-struct";
|
||||||
|
|
||||||
|
char text[16]; // plenty enough space for the small integers.
|
||||||
|
snprintf(text, sizeof(text), "%d-", sampler.structReturnIndex);
|
||||||
|
mangledName += text;
|
||||||
|
} else {
|
||||||
|
switch (sampler.getVectorSize()) {
|
||||||
|
case 1: mangledName += "1"; break;
|
||||||
|
case 2: mangledName += "2"; break;
|
||||||
|
case 3: mangledName += "3"; break;
|
||||||
|
case 4: break; // default to prior name mangle behavior
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sampler.ms)
|
if (sampler.ms)
|
||||||
mangledName += "M";
|
mangledName += "M";
|
||||||
break;
|
break;
|
||||||
case EbtStruct:
|
case EbtStruct:
|
||||||
|
case EbtBlock:
|
||||||
|
if (basicType == EbtStruct)
|
||||||
mangledName += "struct-";
|
mangledName += "struct-";
|
||||||
|
else
|
||||||
|
mangledName += "block-";
|
||||||
if (typeName)
|
if (typeName)
|
||||||
mangledName += *typeName;
|
mangledName += *typeName;
|
||||||
for (unsigned int i = 0; i < structure->size(); ++i) {
|
for (unsigned int i = 0; i < structure->size(); ++i) {
|
||||||
|
@ -292,6 +322,9 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
|
||||||
op = copyOf.op;
|
op = copyOf.op;
|
||||||
defined = copyOf.defined;
|
defined = copyOf.defined;
|
||||||
prototyped = copyOf.prototyped;
|
prototyped = copyOf.prototyped;
|
||||||
|
implicitThis = copyOf.implicitThis;
|
||||||
|
illegalImplicitThis = copyOf.illegalImplicitThis;
|
||||||
|
defaultParamCount = copyOf.defaultParamCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
TFunction* TFunction::clone() const
|
TFunction* TFunction::clone() const
|
||||||
|
@ -315,6 +348,7 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
||||||
{
|
{
|
||||||
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
|
||||||
symTableLevel->anonId = anonId;
|
symTableLevel->anonId = anonId;
|
||||||
|
symTableLevel->thisLevel = thisLevel;
|
||||||
std::vector<bool> containerCopied(anonId, false);
|
std::vector<bool> containerCopied(anonId, false);
|
||||||
tLevel::const_iterator iter;
|
tLevel::const_iterator iter;
|
||||||
for (iter = level.begin(); iter != level.end(); ++iter) {
|
for (iter = level.begin(); iter != level.end(); ++iter) {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _SYMBOL_TABLE_INCLUDED_
|
#ifndef _SYMBOL_TABLE_INCLUDED_
|
||||||
|
@ -87,6 +87,12 @@ public:
|
||||||
|
|
||||||
virtual const TString& getName() const { return *name; }
|
virtual const TString& getName() const { return *name; }
|
||||||
virtual void changeName(const TString* newName) { name = newName; }
|
virtual void changeName(const TString* newName) { name = newName; }
|
||||||
|
virtual void addPrefix(const char* prefix)
|
||||||
|
{
|
||||||
|
TString newName(prefix);
|
||||||
|
newName.append(*name);
|
||||||
|
changeName(NewPoolTString(newName.c_str()));
|
||||||
|
}
|
||||||
virtual const TString& getMangledName() const { return getName(); }
|
virtual const TString& getMangledName() const { return getName(); }
|
||||||
virtual TFunction* getAsFunction() { return 0; }
|
virtual TFunction* getAsFunction() { return 0; }
|
||||||
virtual const TFunction* getAsFunction() const { return 0; }
|
virtual const TFunction* getAsFunction() const { return 0; }
|
||||||
|
@ -147,7 +153,8 @@ public:
|
||||||
TVariable(const TString *name, const TType& t, bool uT = false )
|
TVariable(const TString *name, const TType& t, bool uT = false )
|
||||||
: TSymbol(name),
|
: TSymbol(name),
|
||||||
userType(uT),
|
userType(uT),
|
||||||
constSubtree(nullptr) { type.shallowCopy(t); }
|
constSubtree(nullptr),
|
||||||
|
anonId(-1) { type.shallowCopy(t); }
|
||||||
virtual TVariable* clone() const;
|
virtual TVariable* clone() const;
|
||||||
virtual ~TVariable() { }
|
virtual ~TVariable() { }
|
||||||
|
|
||||||
|
@ -161,6 +168,8 @@ public:
|
||||||
virtual void setConstArray(const TConstUnionArray& array) { constArray = array; }
|
virtual void setConstArray(const TConstUnionArray& array) { constArray = array; }
|
||||||
virtual void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
virtual void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
||||||
virtual TIntermTyped* getConstSubtree() const { return constSubtree; }
|
virtual TIntermTyped* getConstSubtree() const { return constSubtree; }
|
||||||
|
virtual void setAnonId(int i) { anonId = i; }
|
||||||
|
virtual int getAnonId() const { return anonId; }
|
||||||
|
|
||||||
virtual void dump(TInfoSink &infoSink) const;
|
virtual void dump(TInfoSink &infoSink) const;
|
||||||
|
|
||||||
|
@ -178,6 +187,7 @@ protected:
|
||||||
// constant, or neither, but never both.
|
// constant, or neither, but never both.
|
||||||
TConstUnionArray constArray; // for compile-time constant value
|
TConstUnionArray constArray; // for compile-time constant value
|
||||||
TIntermTyped* constSubtree; // for specialization constant computation
|
TIntermTyped* constSubtree; // for specialization constant computation
|
||||||
|
int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -187,6 +197,7 @@ protected:
|
||||||
struct TParameter {
|
struct TParameter {
|
||||||
TString *name;
|
TString *name;
|
||||||
TType* type;
|
TType* type;
|
||||||
|
TIntermTyped* defaultValue;
|
||||||
void copyParam(const TParameter& param)
|
void copyParam(const TParameter& param)
|
||||||
{
|
{
|
||||||
if (param.name)
|
if (param.name)
|
||||||
|
@ -194,7 +205,9 @@ struct TParameter {
|
||||||
else
|
else
|
||||||
name = 0;
|
name = 0;
|
||||||
type = param.type->clone();
|
type = param.type->clone();
|
||||||
|
defaultValue = param.defaultValue;
|
||||||
}
|
}
|
||||||
|
TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -205,40 +218,82 @@ public:
|
||||||
explicit TFunction(TOperator o) :
|
explicit TFunction(TOperator o) :
|
||||||
TSymbol(0),
|
TSymbol(0),
|
||||||
op(o),
|
op(o),
|
||||||
defined(false), prototyped(false) { }
|
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { }
|
||||||
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
|
TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
|
||||||
TSymbol(name),
|
TSymbol(name),
|
||||||
mangledName(*name + '('),
|
mangledName(*name + '('),
|
||||||
op(tOp),
|
op(tOp),
|
||||||
defined(false), prototyped(false) { returnType.shallowCopy(retType); }
|
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0)
|
||||||
virtual TFunction* clone() const;
|
{
|
||||||
|
returnType.shallowCopy(retType);
|
||||||
|
declaredBuiltIn = retType.getQualifier().builtIn;
|
||||||
|
}
|
||||||
|
virtual TFunction* clone() const override;
|
||||||
virtual ~TFunction();
|
virtual ~TFunction();
|
||||||
|
|
||||||
virtual TFunction* getAsFunction() { return this; }
|
virtual TFunction* getAsFunction() override { return this; }
|
||||||
virtual const TFunction* getAsFunction() const { return this; }
|
virtual const TFunction* getAsFunction() const override { return this; }
|
||||||
|
|
||||||
|
// Install 'p' as the (non-'this') last parameter.
|
||||||
|
// Non-'this' parameters are reflected in both the list of parameters and the
|
||||||
|
// mangled name.
|
||||||
virtual void addParameter(TParameter& p)
|
virtual void addParameter(TParameter& p)
|
||||||
{
|
{
|
||||||
assert(writable);
|
assert(writable);
|
||||||
parameters.push_back(p);
|
parameters.push_back(p);
|
||||||
p.type->appendMangledName(mangledName);
|
p.type->appendMangledName(mangledName);
|
||||||
|
|
||||||
|
if (p.defaultValue != nullptr)
|
||||||
|
defaultParamCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const TString& getMangledName() const { return mangledName; }
|
// Install 'this' as the first parameter.
|
||||||
virtual const TType& getType() const { return returnType; }
|
// 'this' is reflected in the list of parameters, but not the mangled name.
|
||||||
virtual TType& getWritableType() { return returnType; }
|
virtual void addThisParameter(TType& type, const char* name)
|
||||||
|
{
|
||||||
|
TParameter p = { NewPoolTString(name), new TType, nullptr };
|
||||||
|
p.type->shallowCopy(type);
|
||||||
|
parameters.insert(parameters.begin(), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void addPrefix(const char* prefix) override
|
||||||
|
{
|
||||||
|
TSymbol::addPrefix(prefix);
|
||||||
|
mangledName.insert(0, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void removePrefix(const TString& prefix)
|
||||||
|
{
|
||||||
|
assert(mangledName.compare(0, prefix.size(), prefix) == 0);
|
||||||
|
mangledName.erase(0, prefix.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const TString& getMangledName() const override { return mangledName; }
|
||||||
|
virtual const TType& getType() const override { return returnType; }
|
||||||
|
virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
|
||||||
|
virtual TType& getWritableType() override { return returnType; }
|
||||||
virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
|
virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
|
||||||
virtual TOperator getBuiltInOp() const { return op; }
|
virtual TOperator getBuiltInOp() const { return op; }
|
||||||
virtual void setDefined() { assert(writable); defined = true; }
|
virtual void setDefined() { assert(writable); defined = true; }
|
||||||
virtual bool isDefined() const { return defined; }
|
virtual bool isDefined() const { return defined; }
|
||||||
virtual void setPrototyped() { assert(writable); prototyped = true; }
|
virtual void setPrototyped() { assert(writable); prototyped = true; }
|
||||||
virtual bool isPrototyped() const { return prototyped; }
|
virtual bool isPrototyped() const { return prototyped; }
|
||||||
|
virtual void setImplicitThis() { assert(writable); implicitThis = true; }
|
||||||
|
virtual bool hasImplicitThis() const { return implicitThis; }
|
||||||
|
virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; }
|
||||||
|
virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; }
|
||||||
|
|
||||||
|
// Return total number of parameters
|
||||||
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
|
virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
|
||||||
|
// Return number of parameters with default values.
|
||||||
|
virtual int getDefaultParamCount() const { return defaultParamCount; }
|
||||||
|
// Return number of fixed parameters (without default values)
|
||||||
|
virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); }
|
||||||
|
|
||||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||||
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
virtual const TParameter& operator[](int i) const { return parameters[i]; }
|
||||||
|
|
||||||
virtual void dump(TInfoSink &infoSink) const;
|
virtual void dump(TInfoSink &infoSink) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TFunction(const TFunction&);
|
explicit TFunction(const TFunction&);
|
||||||
|
@ -247,10 +302,18 @@ protected:
|
||||||
typedef TVector<TParameter> TParamList;
|
typedef TVector<TParameter> TParamList;
|
||||||
TParamList parameters;
|
TParamList parameters;
|
||||||
TType returnType;
|
TType returnType;
|
||||||
|
TBuiltInVariable declaredBuiltIn;
|
||||||
|
|
||||||
TString mangledName;
|
TString mangledName;
|
||||||
TOperator op;
|
TOperator op;
|
||||||
bool defined;
|
bool defined;
|
||||||
bool prototyped;
|
bool prototyped;
|
||||||
|
bool implicitThis; // True if this function is allowed to see all members of 'this'
|
||||||
|
bool illegalImplicitThis; // True if this function is not supposed to have access to dynamic members of 'this',
|
||||||
|
// even if it finds member variables in the symbol table.
|
||||||
|
// 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -297,7 +360,7 @@ protected:
|
||||||
class TSymbolTableLevel {
|
class TSymbolTableLevel {
|
||||||
public:
|
public:
|
||||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||||
TSymbolTableLevel() : defaultPrecision(0), anonId(0) { }
|
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
|
||||||
~TSymbolTableLevel();
|
~TSymbolTableLevel();
|
||||||
|
|
||||||
bool insert(TSymbol& symbol, bool separateNameSpaces)
|
bool insert(TSymbol& symbol, bool separateNameSpaces)
|
||||||
|
@ -305,27 +368,16 @@ public:
|
||||||
//
|
//
|
||||||
// returning true means symbol was added to the table with no semantic errors
|
// returning true means symbol was added to the table with no semantic errors
|
||||||
//
|
//
|
||||||
tInsertResult result;
|
|
||||||
const TString& name = symbol.getName();
|
const TString& name = symbol.getName();
|
||||||
if (name == "") {
|
if (name == "") {
|
||||||
|
symbol.getAsVariable()->setAnonId(anonId++);
|
||||||
// An empty name means an anonymous container, exposing its members to the external scope.
|
// 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.
|
// Give it a name and insert its members in the symbol table, pointing to the container.
|
||||||
char buf[20];
|
char buf[20];
|
||||||
snprintf(buf, 20, "%s%d", AnonymousPrefix, anonId);
|
snprintf(buf, 20, "%s%d", AnonymousPrefix, symbol.getAsVariable()->getAnonId());
|
||||||
symbol.changeName(NewPoolTString(buf));
|
symbol.changeName(NewPoolTString(buf));
|
||||||
|
|
||||||
bool isOkay = true;
|
return insertAnonymousMembers(symbol, 0);
|
||||||
const TTypeList& types = *symbol.getAsVariable()->getType().getStruct();
|
|
||||||
for (unsigned int m = 0; m < types.size(); ++m) {
|
|
||||||
TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), anonId);
|
|
||||||
result = level.insert(tLevelPair(member->getMangledName(), member));
|
|
||||||
if (! result.second)
|
|
||||||
isOkay = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
++anonId;
|
|
||||||
|
|
||||||
return isOkay;
|
|
||||||
} else {
|
} else {
|
||||||
// Check for redefinition errors:
|
// Check for redefinition errors:
|
||||||
// - STL itself will tell us if there is a direct name collision, with name mangling, at this level
|
// - STL itself will tell us if there is a direct name collision, with name mangling, at this level
|
||||||
|
@ -340,12 +392,33 @@ public:
|
||||||
level.insert(tLevelPair(insertName, &symbol));
|
level.insert(tLevelPair(insertName, &symbol));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else
|
||||||
result = level.insert(tLevelPair(insertName, &symbol));
|
return level.insert(tLevelPair(insertName, &symbol)).second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result.second;
|
// Add more members to an already inserted aggregate object
|
||||||
|
bool amend(TSymbol& symbol, int firstNewMember)
|
||||||
|
{
|
||||||
|
// See insert() for comments on basic explanation of insert.
|
||||||
|
// This operates similarly, but more simply.
|
||||||
|
// Only supporting amend of anonymous blocks so far.
|
||||||
|
if (IsAnonymous(symbol.getName()))
|
||||||
|
return insertAnonymousMembers(symbol, firstNewMember);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool insertAnonymousMembers(TSymbol& symbol, int firstMember)
|
||||||
|
{
|
||||||
|
const TTypeList& types = *symbol.getAsVariable()->getType().getStruct();
|
||||||
|
for (unsigned int m = firstMember; m < types.size(); ++m) {
|
||||||
|
TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), symbol.getAsVariable()->getAnonId());
|
||||||
|
if (! level.insert(tLevelPair(member->getMangledName(), member)).second)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSymbol* find(const TString& name) const
|
TSymbol* find(const TString& name) const
|
||||||
|
@ -357,7 +430,7 @@ public:
|
||||||
return (*it).second;
|
return (*it).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void findFunctionNameList(const TString& name, TVector<TFunction*>& list)
|
void findFunctionNameList(const TString& name, TVector<const TFunction*>& list)
|
||||||
{
|
{
|
||||||
size_t parenAt = name.find_first_of('(');
|
size_t parenAt = name.find_first_of('(');
|
||||||
TString base(name, 0, parenAt + 1);
|
TString base(name, 0, parenAt + 1);
|
||||||
|
@ -445,6 +518,9 @@ public:
|
||||||
TSymbolTableLevel* clone() const;
|
TSymbolTableLevel* clone() const;
|
||||||
void readOnly();
|
void readOnly();
|
||||||
|
|
||||||
|
void setThisLevel() { thisLevel = true; }
|
||||||
|
bool isThisLevel() const { return thisLevel; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TSymbolTableLevel(TSymbolTableLevel&);
|
explicit TSymbolTableLevel(TSymbolTableLevel&);
|
||||||
TSymbolTableLevel& operator=(TSymbolTableLevel&);
|
TSymbolTableLevel& operator=(TSymbolTableLevel&);
|
||||||
|
@ -456,6 +532,8 @@ protected:
|
||||||
tLevel level; // named mappings
|
tLevel level; // named mappings
|
||||||
TPrecisionQualifier *defaultPrecision;
|
TPrecisionQualifier *defaultPrecision;
|
||||||
int anonId;
|
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.
|
||||||
};
|
};
|
||||||
|
|
||||||
class TSymbolTable {
|
class TSymbolTable {
|
||||||
|
@ -512,6 +590,20 @@ public:
|
||||||
table.push_back(new TSymbolTableLevel);
|
table.push_back(new TSymbolTableLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make a new symbol-table level to represent the scope introduced by a structure
|
||||||
|
// containing member functions, such that the member functions can find anonymous
|
||||||
|
// references to member variables.
|
||||||
|
//
|
||||||
|
// 'thisSymbol' should have a name of "" to trigger anonymous structure-member
|
||||||
|
// symbol finds.
|
||||||
|
void pushThis(TSymbol& thisSymbol)
|
||||||
|
{
|
||||||
|
assert(thisSymbol.getName().size() == 0);
|
||||||
|
table.push_back(new TSymbolTableLevel);
|
||||||
|
table.back()->setThisLevel();
|
||||||
|
insert(thisSymbol);
|
||||||
|
}
|
||||||
|
|
||||||
void pop(TPrecisionQualifier *p)
|
void pop(TPrecisionQualifier *p)
|
||||||
{
|
{
|
||||||
table[currentLevel()]->getPreviousDefaultPrecisions(p);
|
table[currentLevel()]->getPreviousDefaultPrecisions(p);
|
||||||
|
@ -546,6 +638,14 @@ public:
|
||||||
return table[currentLevel()]->insert(symbol, separateNameSpaces);
|
return table[currentLevel()]->insert(symbol, separateNameSpaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add more members to an already inserted aggregate object
|
||||||
|
bool amend(TSymbol& symbol, int firstNewMember)
|
||||||
|
{
|
||||||
|
// See insert() for comments on basic explanation of insert.
|
||||||
|
// This operates similarly, but more simply.
|
||||||
|
return table[currentLevel()]->amend(symbol, firstNewMember);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// To allocate an internal temporary, which will need to be uniquely
|
// To allocate an internal temporary, which will need to be uniquely
|
||||||
// identified by the consumer of the AST, but never need to
|
// identified by the consumer of the AST, but never need to
|
||||||
|
@ -590,19 +690,50 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TSymbol* find(const TString& name, bool* builtIn = 0, bool *currentScope = 0)
|
// Normal find of a symbol, that can optionally say whether the symbol was found
|
||||||
|
// at a built-in level or the current top-scope level.
|
||||||
|
TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0)
|
||||||
{
|
{
|
||||||
int level = currentLevel();
|
int level = currentLevel();
|
||||||
TSymbol* symbol;
|
TSymbol* symbol;
|
||||||
|
int thisDepth = 0;
|
||||||
do {
|
do {
|
||||||
|
if (table[level]->isThisLevel())
|
||||||
|
++thisDepth;
|
||||||
symbol = table[level]->find(name);
|
symbol = table[level]->find(name);
|
||||||
--level;
|
--level;
|
||||||
} while (symbol == 0 && level >= 0);
|
} while (symbol == nullptr && level >= 0);
|
||||||
level++;
|
level++;
|
||||||
if (builtIn)
|
if (builtIn)
|
||||||
*builtIn = isBuiltInLevel(level);
|
*builtIn = isBuiltInLevel(level);
|
||||||
if (currentScope)
|
if (currentScope)
|
||||||
*currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals
|
*currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals
|
||||||
|
if (thisDepthP != nullptr) {
|
||||||
|
if (! table[level]->isThisLevel())
|
||||||
|
thisDepth = 0;
|
||||||
|
*thisDepthP = thisDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find of a symbol that returns how many layers deep of nested
|
||||||
|
// structures-with-member-functions ('this' scopes) deep the symbol was
|
||||||
|
// found in.
|
||||||
|
TSymbol* find(const TString& name, int& thisDepth)
|
||||||
|
{
|
||||||
|
int level = currentLevel();
|
||||||
|
TSymbol* symbol;
|
||||||
|
thisDepth = 0;
|
||||||
|
do {
|
||||||
|
if (table[level]->isThisLevel())
|
||||||
|
++thisDepth;
|
||||||
|
symbol = table[level]->find(name);
|
||||||
|
--level;
|
||||||
|
} while (symbol == 0 && level >= 0);
|
||||||
|
|
||||||
|
if (! table[level + 1]->isThisLevel())
|
||||||
|
thisDepth = 0;
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
@ -624,7 +755,7 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void findFunctionNameList(const TString& name, TVector<TFunction*>& list, bool& builtIn)
|
void findFunctionNameList(const TString& name, TVector<const TFunction*>& list, bool& builtIn)
|
||||||
{
|
{
|
||||||
// For user levels, return the set found in the first scope with a match
|
// For user levels, return the set found in the first scope with a match
|
||||||
builtIn = false;
|
builtIn = false;
|
||||||
|
|
325
Externals/glslang/glslang/MachineIndependent/Versions.cpp
vendored
Normal file → Executable file
325
Externals/glslang/glslang/MachineIndependent/Versions.cpp
vendored
Normal file → Executable file
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +21,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -154,8 +155,9 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
extensionBehavior[E_GL_OES_standard_derivatives] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable;
|
extensionBehavior[E_GL_EXT_frag_depth] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_EGL_image_external] = EBhDisable;
|
extensionBehavior[E_GL_OES_EGL_image_external] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_OES_EGL_image_external_essl3] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shadow_samplers] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable;
|
extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable;
|
||||||
extensionBehavior[E_GL_3DL_array_objects] = EBhDisable;
|
extensionBehavior[E_GL_3DL_array_objects] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shading_language_420pack] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shading_language_420pack] = EBhDisable;
|
||||||
|
@ -179,14 +181,55 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
|
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
|
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_shader_stencil_export] = EBhDisable;
|
||||||
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
|
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
|
||||||
|
extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable;
|
||||||
|
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_arithmetic] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_ballot] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_clustered] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_shader_subgroup_quad] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
|
||||||
|
|
||||||
// #line and #include
|
// #line and #include
|
||||||
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
||||||
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_gcn_shader] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_gpu_shader_half_float] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_texture_gather_bias_lod] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_gpu_shader_int16] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = EBhDisable;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
|
||||||
|
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_viewport_array2] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_stereo_view_rendering] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NVX_multiview_per_view_attributes] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_shader_atomic_int64] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_conservative_raster_underestimation] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_shader_noperspective_interpolation] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
|
||||||
|
#endif
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
|
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisable;
|
extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisable;
|
||||||
|
@ -214,6 +257,24 @@ void TParseVersions::initializeExtensionBehavior()
|
||||||
extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable;
|
extensionBehavior[E_GL_OES_tessellation_point_size] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_buffer] = EBhDisable;
|
||||||
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
extensionBehavior[E_GL_OES_texture_cube_map_array] = EBhDisable;
|
||||||
|
|
||||||
|
// EXT extensions
|
||||||
|
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_multiview] = EBhDisable;
|
||||||
|
|
||||||
|
// OVR extensions
|
||||||
|
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_OVR_multiview2] = EBhDisable;
|
||||||
|
|
||||||
|
// explicit types
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int8] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int16] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int32] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_int64] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float16] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float32] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHX_shader_explicit_arithmetic_types_float64] = EBhDisable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get code that is not part of a shared symbol table, is specific to this shader,
|
// Get code that is not part of a shared symbol table, is specific to this shader,
|
||||||
|
@ -228,7 +289,9 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_OES_standard_derivatives 1\n"
|
"#define GL_OES_standard_derivatives 1\n"
|
||||||
"#define GL_EXT_frag_depth 1\n"
|
"#define GL_EXT_frag_depth 1\n"
|
||||||
"#define GL_OES_EGL_image_external 1\n"
|
"#define GL_OES_EGL_image_external 1\n"
|
||||||
|
"#define GL_OES_EGL_image_external_essl3 1\n"
|
||||||
"#define GL_EXT_shader_texture_lod 1\n"
|
"#define GL_EXT_shader_texture_lod 1\n"
|
||||||
|
"#define GL_EXT_shadow_samplers 1\n"
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
"#define GL_ANDROID_extension_pack_es31a 1\n"
|
"#define GL_ANDROID_extension_pack_es31a 1\n"
|
||||||
|
@ -259,6 +322,13 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_OES_texture_cube_map_array 1\n"
|
"#define GL_OES_texture_cube_map_array 1\n"
|
||||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
if (profile == EEsProfile && version >= 300) {
|
||||||
|
preamble += "#define GL_NV_shader_noperspective_interpolation 1\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
preamble =
|
preamble =
|
||||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||||
|
@ -284,8 +354,77 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
"#define GL_ARB_shader_ballot 1\n"
|
"#define GL_ARB_shader_ballot 1\n"
|
||||||
"#define GL_ARB_sparse_texture2 1\n"
|
"#define GL_ARB_sparse_texture2 1\n"
|
||||||
"#define GL_ARB_sparse_texture_clamp 1\n"
|
"#define GL_ARB_sparse_texture_clamp 1\n"
|
||||||
|
"#define GL_ARB_shader_stencil_export 1\n"
|
||||||
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
||||||
|
"#define GL_ARB_post_depth_coverage 1\n"
|
||||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||||
|
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||||
|
"#define GL_EXT_post_depth_coverage 1\n"
|
||||||
|
"#define GL_EXT_control_flow_attributes 1\n"
|
||||||
|
"#define GL_EXT_nonuniform_qualifier 1\n"
|
||||||
|
|
||||||
|
// GL_KHR_shader_subgroup
|
||||||
|
"#define GL_KHR_shader_subgroup_basic 1\n"
|
||||||
|
"#define GL_KHR_shader_subgroup_vote 1\n"
|
||||||
|
"#define GL_KHR_shader_subgroup_arithmetic 1\n"
|
||||||
|
"#define GL_KHR_shader_subgroup_ballot 1\n"
|
||||||
|
"#define GL_KHR_shader_subgroup_shuffle 1\n"
|
||||||
|
"#define GL_KHR_shader_subgroup_shuffle_relative 1\n"
|
||||||
|
"#define GL_KHR_shader_subgroup_clustered 1\n"
|
||||||
|
"#define GL_KHR_shader_subgroup_quad 1\n"
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
"#define GL_AMD_shader_ballot 1\n"
|
||||||
|
"#define GL_AMD_shader_trinary_minmax 1\n"
|
||||||
|
"#define GL_AMD_shader_explicit_vertex_parameter 1\n"
|
||||||
|
"#define GL_AMD_gcn_shader 1\n"
|
||||||
|
"#define GL_AMD_gpu_shader_half_float 1\n"
|
||||||
|
"#define GL_AMD_texture_gather_bias_lod 1\n"
|
||||||
|
"#define GL_AMD_gpu_shader_int16 1\n"
|
||||||
|
"#define GL_AMD_shader_image_load_store_lod 1\n"
|
||||||
|
"#define GL_AMD_shader_fragment_mask 1\n"
|
||||||
|
"#define GL_AMD_gpu_shader_half_float_fetch 1\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
"#define GL_NV_sample_mask_override_coverage 1\n"
|
||||||
|
"#define GL_NV_geometry_shader_passthrough 1\n"
|
||||||
|
"#define GL_NV_viewport_array2 1\n"
|
||||||
|
"#define GL_NV_shader_atomic_int64 1\n"
|
||||||
|
"#define GL_NV_conservative_raster_underestimation 1\n"
|
||||||
|
"#define GL_NV_shader_subgroup_partitioned 1\n"
|
||||||
|
#endif
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types 1\n"
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types_int8 1\n"
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types_int16 1\n"
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types_int32 1\n"
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types_int64 1\n"
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types_float16 1\n"
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types_float32 1\n"
|
||||||
|
"#define GL_KHX_shader_explicit_arithmetic_types_float64 1\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
if (version >= 150) {
|
||||||
|
// define GL_core_profile and GL_compatibility_profile
|
||||||
|
preamble += "#define GL_core_profile 1\n";
|
||||||
|
|
||||||
|
if (profile == ECompatibilityProfile)
|
||||||
|
preamble += "#define GL_compatibility_profile 1\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 140) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
preamble +=
|
||||||
|
"#define GL_EXT_device_group 1\n"
|
||||||
|
"#define GL_EXT_multiview 1\n"
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version >= 300 /* both ES and non-ES */) {
|
||||||
|
preamble +=
|
||||||
|
"#define GL_OVR_multiview 1\n"
|
||||||
|
"#define GL_OVR_multiview2 1\n"
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,9 +437,9 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||||
// #define VULKAN XXXX
|
// #define VULKAN XXXX
|
||||||
const int numberBufSize = 12;
|
const int numberBufSize = 12;
|
||||||
char numberBuf[numberBufSize];
|
char numberBuf[numberBufSize];
|
||||||
if (spvVersion.vulkan > 0) {
|
if (spvVersion.vulkanGlsl > 0) {
|
||||||
preamble += "#define VULKAN ";
|
preamble += "#define VULKAN ";
|
||||||
snprintf(numberBuf, numberBufSize, "%d", spvVersion.vulkan);
|
snprintf(numberBuf, numberBufSize, "%d", spvVersion.vulkanGlsl);
|
||||||
preamble += numberBuf;
|
preamble += numberBuf;
|
||||||
preamble += "\n";
|
preamble += "\n";
|
||||||
}
|
}
|
||||||
|
@ -445,6 +584,11 @@ void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc)
|
||||||
|
{
|
||||||
|
error(loc, "feature not yet implemented", featureDesc, "");
|
||||||
|
}
|
||||||
|
|
||||||
// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
|
// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
|
||||||
// Warns appropriately if the requested behavior of an extension is "warn".
|
// Warns appropriately if the requested behavior of an extension is "warn".
|
||||||
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
|
@ -480,7 +624,8 @@ bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExte
|
||||||
//
|
//
|
||||||
void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return;
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
||||||
|
return;
|
||||||
|
|
||||||
// If we get this far, give errors explaining what extensions are needed
|
// If we get this far, give errors explaining what extensions are needed
|
||||||
if (numExtensions == 1)
|
if (numExtensions == 1)
|
||||||
|
@ -498,7 +643,8 @@ void TParseVersions::requireExtensions(const TSourceLoc& loc, int numExtensions,
|
||||||
//
|
//
|
||||||
void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
void TParseVersions::ppRequireExtensions(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
{
|
{
|
||||||
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc)) return;
|
if (checkExtensionsRequested(loc, numExtensions, extensions, featureDesc))
|
||||||
|
return;
|
||||||
|
|
||||||
// If we get this far, give errors explaining what extensions are needed
|
// If we get this far, give errors explaining what extensions are needed
|
||||||
if (numExtensions == 1)
|
if (numExtensions == 1)
|
||||||
|
@ -536,7 +682,8 @@ bool TParseVersions::extensionTurnedOn(const char* const extension)
|
||||||
bool TParseVersions::extensionsTurnedOn(int numExtensions, const char* const extensions[])
|
bool TParseVersions::extensionsTurnedOn(int numExtensions, const char* const extensions[])
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numExtensions; ++i) {
|
for (int i = 0; i < numExtensions; ++i) {
|
||||||
if (extensionTurnedOn(extensions[i])) return true;
|
if (extensionTurnedOn(extensions[i]))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -592,6 +739,25 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
||||||
updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
|
updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString);
|
||||||
else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0)
|
else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0)
|
||||||
updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
|
updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString);
|
||||||
|
// subgroup_* to subgroup_basic
|
||||||
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_vote") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_arithmetic") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_ballot") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_shuffle") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_shuffle_relative") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_clustered") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
||||||
|
@ -649,11 +815,118 @@ void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
||||||
profileRequires(loc, ECompatibilityProfile, 400, nullptr, op);
|
profileRequires(loc, ECompatibilityProfile, 400, nullptr, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call for any operation needing GLSL float16 data-type support.
|
||||||
|
void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (!builtIn) {
|
||||||
|
#if AMD_EXTENSIONS
|
||||||
|
const char* const extensions[3] = {E_GL_AMD_gpu_shader_half_float,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_float16};
|
||||||
|
|
||||||
|
#else
|
||||||
|
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_float16};
|
||||||
|
#endif
|
||||||
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types");
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call for any operation needing GLSL float32 data-type support.
|
||||||
|
void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (!builtIn) {
|
||||||
|
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_float32};
|
||||||
|
requireExtensions(loc, 2, extensions, "explicit types");
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call for any operation needing GLSL float64 data-type support.
|
||||||
|
void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (!builtIn) {
|
||||||
|
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_float64};
|
||||||
|
requireExtensions(loc, 2, extensions, "explicit types");
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call for any operation needing GLSL explicit int8 data-type support.
|
||||||
|
void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (! builtIn) {
|
||||||
|
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_int8};
|
||||||
|
requireExtensions(loc, 2, extensions, "explicit types");
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
// Call for any operation needing GLSL float16 opaque-type support
|
||||||
|
void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (! builtIn) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float_fetch, op);
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Call for any operation needing GLSL explicit int16 data-type support.
|
||||||
|
void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (! builtIn) {
|
||||||
|
#if AMD_EXTENSIONS
|
||||||
|
const char* const extensions[3] = {E_GL_AMD_gpu_shader_int16,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_int16};
|
||||||
|
#else
|
||||||
|
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_int16};
|
||||||
|
#endif
|
||||||
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types");
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call for any operation needing GLSL explicit int32 data-type support.
|
||||||
|
void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (! builtIn) {
|
||||||
|
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_int32};
|
||||||
|
requireExtensions(loc, 2, extensions, "explicit types");
|
||||||
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Call for any operation needing GLSL 64-bit integer data-type support.
|
// Call for any operation needing GLSL 64-bit integer data-type support.
|
||||||
void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
requireExtensions(loc, 1, &E_GL_ARB_gpu_shader_int64, "shader int64");
|
const char* const extensions[3] = {E_GL_ARB_gpu_shader_int64,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types,
|
||||||
|
E_GL_KHX_shader_explicit_arithmetic_types_int64};
|
||||||
|
requireExtensions(loc, 3, extensions, "shader int64");
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
profileRequires(loc, ECoreProfile, 450, nullptr, op);
|
||||||
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
|
||||||
|
@ -670,7 +943,7 @@ void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
|
||||||
// Call for any operation removed because Vulkan SPIR-V is being generated.
|
// Call for any operation removed because Vulkan SPIR-V is being generated.
|
||||||
void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
|
void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
if (spvVersion.vulkan >= 100)
|
if (spvVersion.vulkan > 0)
|
||||||
error(loc, "not allowed when using GLSL for Vulkan", op, "");
|
error(loc, "not allowed when using GLSL for Vulkan", op, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2013 LunarG, Inc.
|
// Copyright (C) 2012-2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,18 +21,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
#ifndef _VERSIONS_INCLUDED_
|
#ifndef _VERSIONS_INCLUDED_
|
||||||
#define _VERSIONS_INCLUDED_
|
#define _VERSIONS_INCLUDED_
|
||||||
|
@ -72,14 +73,19 @@ inline const char* ProfileName(EProfile profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// SPIR-V has versions for multiple things; tie them together.
|
// What source rules, validation rules, target language, etc. are needed
|
||||||
// 0 means a target or rule set is not enabled.
|
// desired for SPIR-V?
|
||||||
|
//
|
||||||
|
// 0 means a target or rule set is not enabled (ignore rules from that entity).
|
||||||
|
// Non-0 means to apply semantic rules arising from that version of its rule set.
|
||||||
|
// The union of all requested rule sets will be applied.
|
||||||
//
|
//
|
||||||
struct SpvVersion {
|
struct SpvVersion {
|
||||||
SpvVersion() : spv(0), vulkan(0), openGl(0) {}
|
SpvVersion() : spv(0), vulkanGlsl(0), vulkan(0), openGl(0) {}
|
||||||
unsigned int spv; // the version of the targeted SPIR-V, as defined by SPIR-V in word 1 of the SPIR-V binary header
|
unsigned int spv; // the version of SPIR-V to target, as defined by "word 1" of the SPIR-V binary header
|
||||||
int vulkan; // the version of semantics for Vulkan; e.g., for GLSL from KHR_vulkan_glsl "#define VULKAN"
|
int vulkanGlsl; // the version of GLSL semantics for Vulkan, from GL_KHR_vulkan_glsl, for "#define VULKAN XXX"
|
||||||
int openGl; // the version of semantics for OpenGL; e.g., for GLSL from KHR_vulkan_glsl "#define GL_SPIRV"
|
int vulkan; // the version of Vulkan, for which SPIR-V execution environment rules to use
|
||||||
|
int openGl; // the version of GLSL semantics for OpenGL, from GL_ARB_gl_spirv, for "#define GL_SPIRV XXX"
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -102,7 +108,9 @@ const char* const E_GL_OES_texture_3D = "GL_OES_texture_3D";
|
||||||
const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_derivatives";
|
const char* const E_GL_OES_standard_derivatives = "GL_OES_standard_derivatives";
|
||||||
const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth";
|
const char* const E_GL_EXT_frag_depth = "GL_EXT_frag_depth";
|
||||||
const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
|
const char* const E_GL_OES_EGL_image_external = "GL_OES_EGL_image_external";
|
||||||
|
const char* const E_GL_OES_EGL_image_external_essl3 = "GL_OES_EGL_image_external_essl3";
|
||||||
const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod";
|
const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod";
|
||||||
|
const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers";
|
||||||
|
|
||||||
const char* const E_GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle";
|
const char* const E_GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle";
|
||||||
const char* const E_GL_3DL_array_objects = "GL_3DL_array_objects";
|
const char* const E_GL_3DL_array_objects = "GL_3DL_array_objects";
|
||||||
|
@ -127,14 +135,77 @@ const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int
|
||||||
const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot";
|
const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot";
|
||||||
const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2";
|
const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2";
|
||||||
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
|
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
|
||||||
//const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil_export";
|
||||||
|
// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
||||||
|
const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage";
|
||||||
|
const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array";
|
||||||
|
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_arithmetic = "GL_KHR_shader_subgroup_arithmetic";
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_ballot = "GL_KHR_shader_subgroup_ballot";
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_subgroup_shuffle";
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
|
||||||
|
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
|
||||||
|
|
||||||
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
||||||
|
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
||||||
|
|
||||||
|
// EXT extensions
|
||||||
|
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
|
||||||
|
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
|
||||||
|
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
|
||||||
|
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
||||||
|
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
|
||||||
|
|
||||||
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
|
const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage };
|
||||||
|
const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]);
|
||||||
|
|
||||||
|
// OVR extensions
|
||||||
|
const char* const E_GL_OVR_multiview = "GL_OVR_multiview";
|
||||||
|
const char* const E_GL_OVR_multiview2 = "GL_OVR_multiview2";
|
||||||
|
|
||||||
|
const char* const OVR_multiview_EXTs[] = { E_GL_OVR_multiview, E_GL_OVR_multiview2 };
|
||||||
|
const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multiview_EXTs[0]);
|
||||||
|
|
||||||
// #line and #include
|
// #line and #include
|
||||||
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
||||||
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot";
|
||||||
|
const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax";
|
||||||
|
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
|
||||||
|
const char* const E_GL_AMD_gcn_shader = "GL_AMD_gcn_shader";
|
||||||
|
const char* const E_GL_AMD_gpu_shader_half_float = "GL_AMD_gpu_shader_half_float";
|
||||||
|
const char* const E_GL_AMD_texture_gather_bias_lod = "GL_AMD_texture_gather_bias_lod";
|
||||||
|
const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_shader_int16";
|
||||||
|
const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod";
|
||||||
|
const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask";
|
||||||
|
const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
|
||||||
|
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
||||||
|
const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
|
||||||
|
const char* const E_GL_NV_viewport_array2 = "GL_NV_viewport_array2";
|
||||||
|
const char* const E_GL_NV_stereo_view_rendering = "GL_NV_stereo_view_rendering";
|
||||||
|
const char* const E_GL_NVX_multiview_per_view_attributes = "GL_NVX_multiview_per_view_attributes";
|
||||||
|
const char* const E_GL_NV_shader_atomic_int64 = "GL_NV_shader_atomic_int64";
|
||||||
|
const char* const E_GL_NV_conservative_raster_underestimation = "GL_NV_conservative_raster_underestimation";
|
||||||
|
const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_noperspective_interpolation";
|
||||||
|
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
|
||||||
|
|
||||||
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
|
const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
|
||||||
|
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
|
||||||
|
#endif
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
||||||
const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced";
|
const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced";
|
||||||
|
@ -163,6 +234,16 @@ const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessel
|
||||||
const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer";
|
const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer";
|
||||||
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
||||||
|
|
||||||
|
// KHX
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types = "GL_KHX_shader_explicit_arithmetic_types";
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int8 = "GL_KHX_shader_explicit_arithmetic_types_int8";
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int16 = "GL_KHX_shader_explicit_arithmetic_types_int16";
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int32 = "GL_KHX_shader_explicit_arithmetic_types_int32";
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types_int64 = "GL_KHX_shader_explicit_arithmetic_types_int64";
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types_float16 = "GL_KHX_shader_explicit_arithmetic_types_float16";
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types_float32 = "GL_KHX_shader_explicit_arithmetic_types_float32";
|
||||||
|
const char* const E_GL_KHX_shader_explicit_arithmetic_types_float64 = "GL_KHX_shader_explicit_arithmetic_types_float64";
|
||||||
|
|
||||||
// Arrays of extensions for the above AEP duplications
|
// Arrays of extensions for the above AEP duplications
|
||||||
|
|
||||||
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
||||||
|
|
|
@ -0,0 +1,257 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 LunarG, Inc.
|
||||||
|
// Copyright (C) 2018 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "attribute.h"
|
||||||
|
#include "../Include/intermediate.h"
|
||||||
|
#include "ParseHelper.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
// extract integers out of attribute arguments stored in attribute aggregate
|
||||||
|
bool TAttributeArgs::getInt(int& value, int argNum) const
|
||||||
|
{
|
||||||
|
const TConstUnion* intConst = getConstUnion(EbtInt, argNum);
|
||||||
|
|
||||||
|
if (intConst == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
value = intConst->getIConst();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract strings out of attribute arguments stored in attribute aggregate.
|
||||||
|
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
|
||||||
|
bool TAttributeArgs::getString(TString& value, int argNum, bool convertToLower) const
|
||||||
|
{
|
||||||
|
const TConstUnion* stringConst = getConstUnion(EbtString, argNum);
|
||||||
|
|
||||||
|
if (stringConst == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
value = *stringConst->getSConst();
|
||||||
|
|
||||||
|
// Convenience.
|
||||||
|
if (convertToLower)
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// How many arguments were supplied?
|
||||||
|
int TAttributeArgs::size() const
|
||||||
|
{
|
||||||
|
return args == nullptr ? 0 : (int)args->getSequence().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to get attribute const union. Returns nullptr on failure.
|
||||||
|
const TConstUnion* TAttributeArgs::getConstUnion(TBasicType basicType, int argNum) const
|
||||||
|
{
|
||||||
|
if (args == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (argNum >= (int)args->getSequence().size())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
|
||||||
|
if (constVal == nullptr || constVal->getType() != basicType)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return constVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation of TParseContext parts of attributes
|
||||||
|
TAttributeType TParseContext::attributeFromName(const TString& name) const
|
||||||
|
{
|
||||||
|
if (name == "branch" || name == "dont_flatten")
|
||||||
|
return EatBranch;
|
||||||
|
else if (name == "flatten")
|
||||||
|
return EatFlatten;
|
||||||
|
else if (name == "unroll")
|
||||||
|
return EatUnroll;
|
||||||
|
else if (name == "loop" || name == "dont_unroll")
|
||||||
|
return EatLoop;
|
||||||
|
else if (name == "dependency_infinite")
|
||||||
|
return EatDependencyInfinite;
|
||||||
|
else if (name == "dependency_length")
|
||||||
|
return EatDependencyLength;
|
||||||
|
else
|
||||||
|
return EatNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make an initial leaf for the grammar from a no-argument attribute
|
||||||
|
TAttributes* TParseContext::makeAttributes(const TString& identifier) const
|
||||||
|
{
|
||||||
|
TAttributes *attributes = nullptr;
|
||||||
|
attributes = NewPoolObject(attributes);
|
||||||
|
TAttributeArgs args = { attributeFromName(identifier), nullptr };
|
||||||
|
attributes->push_back(args);
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make an initial leaf for the grammar from a one-argument attribute
|
||||||
|
TAttributes* TParseContext::makeAttributes(const TString& identifier, TIntermNode* node) const
|
||||||
|
{
|
||||||
|
TAttributes *attributes = nullptr;
|
||||||
|
attributes = NewPoolObject(attributes);
|
||||||
|
|
||||||
|
// for now, node is always a simple single expression, but other code expects
|
||||||
|
// a list, so make it so
|
||||||
|
TIntermAggregate* agg = intermediate.makeAggregate(node);
|
||||||
|
TAttributeArgs args = { attributeFromName(identifier), agg };
|
||||||
|
attributes->push_back(args);
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge two sets of attributes into a single set.
|
||||||
|
// The second argument is destructively consumed.
|
||||||
|
TAttributes* TParseContext::mergeAttributes(TAttributes* attr1, TAttributes* attr2) const
|
||||||
|
{
|
||||||
|
attr1->splice(attr1->end(), *attr2);
|
||||||
|
return attr1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Selection attributes
|
||||||
|
//
|
||||||
|
void TParseContext::handleSelectionAttributes(const TAttributes& attributes, TIntermNode* node)
|
||||||
|
{
|
||||||
|
TIntermSelection* selection = node->getAsSelectionNode();
|
||||||
|
if (selection == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||||
|
if (it->size() > 0) {
|
||||||
|
warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (it->name) {
|
||||||
|
case EatFlatten:
|
||||||
|
selection->setFlatten();
|
||||||
|
break;
|
||||||
|
case EatBranch:
|
||||||
|
selection->setDontFlatten();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warn(node->getLoc(), "attribute does not apply to a selection", "", "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Switch attributes
|
||||||
|
//
|
||||||
|
void TParseContext::handleSwitchAttributes(const TAttributes& attributes, TIntermNode* node)
|
||||||
|
{
|
||||||
|
TIntermSwitch* selection = node->getAsSwitchNode();
|
||||||
|
if (selection == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||||
|
if (it->size() > 0) {
|
||||||
|
warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (it->name) {
|
||||||
|
case EatFlatten:
|
||||||
|
selection->setFlatten();
|
||||||
|
break;
|
||||||
|
case EatBranch:
|
||||||
|
selection->setDontFlatten();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warn(node->getLoc(), "attribute does not apply to a switch", "", "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Loop attributes
|
||||||
|
//
|
||||||
|
void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermNode* node)
|
||||||
|
{
|
||||||
|
TIntermLoop* loop = node->getAsLoopNode();
|
||||||
|
if (loop == nullptr) {
|
||||||
|
// the actual loop might be part of a sequence
|
||||||
|
TIntermAggregate* agg = node->getAsAggregate();
|
||||||
|
if (agg == nullptr)
|
||||||
|
return;
|
||||||
|
for (auto it = agg->getSequence().begin(); it != agg->getSequence().end(); ++it) {
|
||||||
|
loop = (*it)->getAsLoopNode();
|
||||||
|
if (loop != nullptr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (loop == nullptr)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||||
|
if (it->name != EatDependencyLength && it->size() > 0) {
|
||||||
|
warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int value;
|
||||||
|
switch (it->name) {
|
||||||
|
case EatUnroll:
|
||||||
|
loop->setUnroll();
|
||||||
|
break;
|
||||||
|
case EatLoop:
|
||||||
|
loop->setDontUnroll();
|
||||||
|
break;
|
||||||
|
case EatDependencyInfinite:
|
||||||
|
loop->setLoopDependency(TIntermLoop::dependencyInfinite);
|
||||||
|
break;
|
||||||
|
case EatDependencyLength:
|
||||||
|
if (it->size() == 1 && it->getInt(value)) {
|
||||||
|
if (value <= 0)
|
||||||
|
error(node->getLoc(), "must be positive", "dependency_length", "");
|
||||||
|
loop->setLoopDependency(value);
|
||||||
|
} else
|
||||||
|
warn(node->getLoc(), "expected a single integer argument", "dependency_length", "");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warn(node->getLoc(), "attribute does not apply to a loop", "", "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace glslang
|
|
@ -0,0 +1,102 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 LunarG, Inc.
|
||||||
|
// Copyright (C) 2018 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef _ATTRIBUTE_INCLUDED_
|
||||||
|
#define _ATTRIBUTE_INCLUDED_
|
||||||
|
|
||||||
|
#include "../Include/Common.h"
|
||||||
|
#include "../Include/ConstantUnion.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
enum TAttributeType {
|
||||||
|
EatNone,
|
||||||
|
EatAllow_uav_condition,
|
||||||
|
EatBranch,
|
||||||
|
EatCall,
|
||||||
|
EatDomain,
|
||||||
|
EatEarlyDepthStencil,
|
||||||
|
EatFastOpt,
|
||||||
|
EatFlatten,
|
||||||
|
EatForceCase,
|
||||||
|
EatInstance,
|
||||||
|
EatMaxTessFactor,
|
||||||
|
EatNumThreads,
|
||||||
|
EatMaxVertexCount,
|
||||||
|
EatOutputControlPoints,
|
||||||
|
EatOutputTopology,
|
||||||
|
EatPartitioning,
|
||||||
|
EatPatchConstantFunc,
|
||||||
|
EatPatchSize,
|
||||||
|
EatUnroll,
|
||||||
|
EatLoop,
|
||||||
|
EatBinding,
|
||||||
|
EatGlobalBinding,
|
||||||
|
EatLocation,
|
||||||
|
EatInputAttachment,
|
||||||
|
EatBuiltIn,
|
||||||
|
EatPushConstant,
|
||||||
|
EatConstantId,
|
||||||
|
EatDependencyInfinite,
|
||||||
|
EatDependencyLength
|
||||||
|
};
|
||||||
|
|
||||||
|
class TIntermAggregate;
|
||||||
|
|
||||||
|
struct TAttributeArgs {
|
||||||
|
TAttributeType name;
|
||||||
|
const TIntermAggregate* args;
|
||||||
|
|
||||||
|
// Obtain attribute as integer
|
||||||
|
// Return false if it cannot be obtained
|
||||||
|
bool getInt(int& value, int argNum = 0) const;
|
||||||
|
|
||||||
|
// Obtain attribute as string, with optional to-lower transform
|
||||||
|
// Return false if it cannot be obtained
|
||||||
|
bool getString(TString& value, int argNum = 0, bool convertToLower = true) const;
|
||||||
|
|
||||||
|
// How many arguments were provided to the attribute?
|
||||||
|
int size() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const TConstUnion* getConstUnion(TBasicType basicType, int argNum) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef TList<TAttributeArgs> TAttributes;
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // _ATTRIBUTE_INCLUDED_
|
|
@ -21,6 +21,8 @@
|
||||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#define GL_FLOAT 0x1406
|
#define GL_FLOAT 0x1406
|
||||||
#define GL_FLOAT_VEC2 0x8B50
|
#define GL_FLOAT_VEC2 0x8B50
|
||||||
#define GL_FLOAT_VEC3 0x8B51
|
#define GL_FLOAT_VEC3 0x8B51
|
||||||
|
@ -76,6 +78,24 @@
|
||||||
#define GL_DOUBLE_MAT4x2 0x8F4D
|
#define GL_DOUBLE_MAT4x2 0x8F4D
|
||||||
#define GL_DOUBLE_MAT4x3 0x8F4E
|
#define GL_DOUBLE_MAT4x3 0x8F4E
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
// Those constants are borrowed from extension NV_gpu_shader5
|
||||||
|
#define GL_FLOAT16_NV 0x8FF8
|
||||||
|
#define GL_FLOAT16_VEC2_NV 0x8FF9
|
||||||
|
#define GL_FLOAT16_VEC3_NV 0x8FFA
|
||||||
|
#define GL_FLOAT16_VEC4_NV 0x8FFB
|
||||||
|
|
||||||
|
#define GL_FLOAT16_MAT2_AMD 0x91C5
|
||||||
|
#define GL_FLOAT16_MAT3_AMD 0x91C6
|
||||||
|
#define GL_FLOAT16_MAT4_AMD 0x91C7
|
||||||
|
#define GL_FLOAT16_MAT2x3_AMD 0x91C8
|
||||||
|
#define GL_FLOAT16_MAT2x4_AMD 0x91C9
|
||||||
|
#define GL_FLOAT16_MAT3x2_AMD 0x91CA
|
||||||
|
#define GL_FLOAT16_MAT3x4_AMD 0x91CB
|
||||||
|
#define GL_FLOAT16_MAT4x2_AMD 0x91CC
|
||||||
|
#define GL_FLOAT16_MAT4x3_AMD 0x91CD
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GL_SAMPLER_1D 0x8B5D
|
#define GL_SAMPLER_1D 0x8B5D
|
||||||
#define GL_SAMPLER_2D 0x8B5E
|
#define GL_SAMPLER_2D 0x8B5E
|
||||||
#define GL_SAMPLER_3D 0x8B5F
|
#define GL_SAMPLER_3D 0x8B5F
|
||||||
|
@ -97,6 +117,40 @@
|
||||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
|
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
|
||||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
|
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF
|
||||||
|
#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0
|
||||||
|
#define GL_FLOAT16_SAMPLER_CUBE_AMD 0x91D1
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_RECT_AMD 0x91D2
|
||||||
|
#define GL_FLOAT16_SAMPLER_1D_ARRAY_AMD 0x91D3
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_ARRAY_AMD 0x91D4
|
||||||
|
#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_AMD 0x91D5
|
||||||
|
#define GL_FLOAT16_SAMPLER_BUFFER_AMD 0x91D6
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_AMD 0x91D7
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_MULTISAMPLE_ARRAY_AMD 0x91D8
|
||||||
|
|
||||||
|
#define GL_FLOAT16_SAMPLER_1D_SHADOW_AMD 0x91D9
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_SHADOW_AMD 0x91DA
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_RECT_SHADOW_AMD 0x91DB
|
||||||
|
#define GL_FLOAT16_SAMPLER_1D_ARRAY_SHADOW_AMD 0x91DC
|
||||||
|
#define GL_FLOAT16_SAMPLER_2D_ARRAY_SHADOW_AMD 0x91DD
|
||||||
|
#define GL_FLOAT16_SAMPLER_CUBE_SHADOW_AMD 0x91DE
|
||||||
|
#define GL_FLOAT16_SAMPLER_CUBE_MAP_ARRAY_SHADOW_AMD 0x91DF
|
||||||
|
|
||||||
|
#define GL_FLOAT16_IMAGE_1D_AMD 0x91E0
|
||||||
|
#define GL_FLOAT16_IMAGE_2D_AMD 0x91E1
|
||||||
|
#define GL_FLOAT16_IMAGE_3D_AMD 0x91E2
|
||||||
|
#define GL_FLOAT16_IMAGE_2D_RECT_AMD 0x91E3
|
||||||
|
#define GL_FLOAT16_IMAGE_CUBE_AMD 0x91E4
|
||||||
|
#define GL_FLOAT16_IMAGE_1D_ARRAY_AMD 0x91E5
|
||||||
|
#define GL_FLOAT16_IMAGE_2D_ARRAY_AMD 0x91E6
|
||||||
|
#define GL_FLOAT16_IMAGE_CUBE_MAP_ARRAY_AMD 0x91E7
|
||||||
|
#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8
|
||||||
|
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9
|
||||||
|
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA
|
||||||
|
#endif
|
||||||
|
|
||||||
#define GL_INT_SAMPLER_1D 0x8DC9
|
#define GL_INT_SAMPLER_1D 0x8DC9
|
||||||
#define GL_INT_SAMPLER_2D 0x8DCA
|
#define GL_INT_SAMPLER_2D 0x8DCA
|
||||||
#define GL_INT_SAMPLER_3D 0x8DCB
|
#define GL_INT_SAMPLER_3D 0x8DCB
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,8 @@
|
||||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
/* A Bison parser, made by GNU Bison 3.0. */
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -47,280 +47,401 @@ extern int yydebug;
|
||||||
{
|
{
|
||||||
ATTRIBUTE = 258,
|
ATTRIBUTE = 258,
|
||||||
VARYING = 259,
|
VARYING = 259,
|
||||||
CONST = 260,
|
FLOAT16_T = 260,
|
||||||
BOOL = 261,
|
FLOAT = 261,
|
||||||
FLOAT = 262,
|
FLOAT32_T = 262,
|
||||||
DOUBLE = 263,
|
DOUBLE = 263,
|
||||||
INT = 264,
|
FLOAT64_T = 264,
|
||||||
UINT = 265,
|
CONST = 265,
|
||||||
INT64_T = 266,
|
BOOL = 266,
|
||||||
UINT64_T = 267,
|
INT = 267,
|
||||||
BREAK = 268,
|
UINT = 268,
|
||||||
CONTINUE = 269,
|
INT64_T = 269,
|
||||||
DO = 270,
|
UINT64_T = 270,
|
||||||
ELSE = 271,
|
INT32_T = 271,
|
||||||
FOR = 272,
|
UINT32_T = 272,
|
||||||
IF = 273,
|
INT16_T = 273,
|
||||||
DISCARD = 274,
|
UINT16_T = 274,
|
||||||
RETURN = 275,
|
INT8_T = 275,
|
||||||
SWITCH = 276,
|
UINT8_T = 276,
|
||||||
CASE = 277,
|
BREAK = 277,
|
||||||
DEFAULT = 278,
|
CONTINUE = 278,
|
||||||
SUBROUTINE = 279,
|
DO = 279,
|
||||||
BVEC2 = 280,
|
ELSE = 280,
|
||||||
BVEC3 = 281,
|
FOR = 281,
|
||||||
BVEC4 = 282,
|
IF = 282,
|
||||||
IVEC2 = 283,
|
DISCARD = 283,
|
||||||
IVEC3 = 284,
|
RETURN = 284,
|
||||||
IVEC4 = 285,
|
SWITCH = 285,
|
||||||
I64VEC2 = 286,
|
CASE = 286,
|
||||||
I64VEC3 = 287,
|
DEFAULT = 287,
|
||||||
I64VEC4 = 288,
|
SUBROUTINE = 288,
|
||||||
UVEC2 = 289,
|
BVEC2 = 289,
|
||||||
UVEC3 = 290,
|
BVEC3 = 290,
|
||||||
UVEC4 = 291,
|
BVEC4 = 291,
|
||||||
U64VEC2 = 292,
|
IVEC2 = 292,
|
||||||
U64VEC3 = 293,
|
IVEC3 = 293,
|
||||||
U64VEC4 = 294,
|
IVEC4 = 294,
|
||||||
VEC2 = 295,
|
UVEC2 = 295,
|
||||||
VEC3 = 296,
|
UVEC3 = 296,
|
||||||
VEC4 = 297,
|
UVEC4 = 297,
|
||||||
MAT2 = 298,
|
I64VEC2 = 298,
|
||||||
MAT3 = 299,
|
I64VEC3 = 299,
|
||||||
MAT4 = 300,
|
I64VEC4 = 300,
|
||||||
CENTROID = 301,
|
U64VEC2 = 301,
|
||||||
IN = 302,
|
U64VEC3 = 302,
|
||||||
OUT = 303,
|
U64VEC4 = 303,
|
||||||
INOUT = 304,
|
I32VEC2 = 304,
|
||||||
UNIFORM = 305,
|
I32VEC3 = 305,
|
||||||
PATCH = 306,
|
I32VEC4 = 306,
|
||||||
SAMPLE = 307,
|
U32VEC2 = 307,
|
||||||
BUFFER = 308,
|
U32VEC3 = 308,
|
||||||
SHARED = 309,
|
U32VEC4 = 309,
|
||||||
COHERENT = 310,
|
I16VEC2 = 310,
|
||||||
VOLATILE = 311,
|
I16VEC3 = 311,
|
||||||
RESTRICT = 312,
|
I16VEC4 = 312,
|
||||||
READONLY = 313,
|
U16VEC2 = 313,
|
||||||
WRITEONLY = 314,
|
U16VEC3 = 314,
|
||||||
DVEC2 = 315,
|
U16VEC4 = 315,
|
||||||
DVEC3 = 316,
|
I8VEC2 = 316,
|
||||||
DVEC4 = 317,
|
I8VEC3 = 317,
|
||||||
DMAT2 = 318,
|
I8VEC4 = 318,
|
||||||
DMAT3 = 319,
|
U8VEC2 = 319,
|
||||||
DMAT4 = 320,
|
U8VEC3 = 320,
|
||||||
NOPERSPECTIVE = 321,
|
U8VEC4 = 321,
|
||||||
FLAT = 322,
|
VEC2 = 322,
|
||||||
SMOOTH = 323,
|
VEC3 = 323,
|
||||||
LAYOUT = 324,
|
VEC4 = 324,
|
||||||
MAT2X2 = 325,
|
MAT2 = 325,
|
||||||
MAT2X3 = 326,
|
MAT3 = 326,
|
||||||
MAT2X4 = 327,
|
MAT4 = 327,
|
||||||
MAT3X2 = 328,
|
CENTROID = 328,
|
||||||
MAT3X3 = 329,
|
IN = 329,
|
||||||
MAT3X4 = 330,
|
OUT = 330,
|
||||||
MAT4X2 = 331,
|
INOUT = 331,
|
||||||
MAT4X3 = 332,
|
UNIFORM = 332,
|
||||||
MAT4X4 = 333,
|
PATCH = 333,
|
||||||
DMAT2X2 = 334,
|
SAMPLE = 334,
|
||||||
DMAT2X3 = 335,
|
BUFFER = 335,
|
||||||
DMAT2X4 = 336,
|
SHARED = 336,
|
||||||
DMAT3X2 = 337,
|
NONUNIFORM = 337,
|
||||||
DMAT3X3 = 338,
|
COHERENT = 338,
|
||||||
DMAT3X4 = 339,
|
VOLATILE = 339,
|
||||||
DMAT4X2 = 340,
|
RESTRICT = 340,
|
||||||
DMAT4X3 = 341,
|
READONLY = 341,
|
||||||
DMAT4X4 = 342,
|
WRITEONLY = 342,
|
||||||
ATOMIC_UINT = 343,
|
DVEC2 = 343,
|
||||||
SAMPLER1D = 344,
|
DVEC3 = 344,
|
||||||
SAMPLER2D = 345,
|
DVEC4 = 345,
|
||||||
SAMPLER3D = 346,
|
DMAT2 = 346,
|
||||||
SAMPLERCUBE = 347,
|
DMAT3 = 347,
|
||||||
SAMPLER1DSHADOW = 348,
|
DMAT4 = 348,
|
||||||
SAMPLER2DSHADOW = 349,
|
F16VEC2 = 349,
|
||||||
SAMPLERCUBESHADOW = 350,
|
F16VEC3 = 350,
|
||||||
SAMPLER1DARRAY = 351,
|
F16VEC4 = 351,
|
||||||
SAMPLER2DARRAY = 352,
|
F16MAT2 = 352,
|
||||||
SAMPLER1DARRAYSHADOW = 353,
|
F16MAT3 = 353,
|
||||||
SAMPLER2DARRAYSHADOW = 354,
|
F16MAT4 = 354,
|
||||||
ISAMPLER1D = 355,
|
F32VEC2 = 355,
|
||||||
ISAMPLER2D = 356,
|
F32VEC3 = 356,
|
||||||
ISAMPLER3D = 357,
|
F32VEC4 = 357,
|
||||||
ISAMPLERCUBE = 358,
|
F32MAT2 = 358,
|
||||||
ISAMPLER1DARRAY = 359,
|
F32MAT3 = 359,
|
||||||
ISAMPLER2DARRAY = 360,
|
F32MAT4 = 360,
|
||||||
USAMPLER1D = 361,
|
F64VEC2 = 361,
|
||||||
USAMPLER2D = 362,
|
F64VEC3 = 362,
|
||||||
USAMPLER3D = 363,
|
F64VEC4 = 363,
|
||||||
USAMPLERCUBE = 364,
|
F64MAT2 = 364,
|
||||||
USAMPLER1DARRAY = 365,
|
F64MAT3 = 365,
|
||||||
USAMPLER2DARRAY = 366,
|
F64MAT4 = 366,
|
||||||
SAMPLER2DRECT = 367,
|
NOPERSPECTIVE = 367,
|
||||||
SAMPLER2DRECTSHADOW = 368,
|
FLAT = 368,
|
||||||
ISAMPLER2DRECT = 369,
|
SMOOTH = 369,
|
||||||
USAMPLER2DRECT = 370,
|
LAYOUT = 370,
|
||||||
SAMPLERBUFFER = 371,
|
__EXPLICITINTERPAMD = 371,
|
||||||
ISAMPLERBUFFER = 372,
|
MAT2X2 = 372,
|
||||||
USAMPLERBUFFER = 373,
|
MAT2X3 = 373,
|
||||||
SAMPLERCUBEARRAY = 374,
|
MAT2X4 = 374,
|
||||||
SAMPLERCUBEARRAYSHADOW = 375,
|
MAT3X2 = 375,
|
||||||
ISAMPLERCUBEARRAY = 376,
|
MAT3X3 = 376,
|
||||||
USAMPLERCUBEARRAY = 377,
|
MAT3X4 = 377,
|
||||||
SAMPLER2DMS = 378,
|
MAT4X2 = 378,
|
||||||
ISAMPLER2DMS = 379,
|
MAT4X3 = 379,
|
||||||
USAMPLER2DMS = 380,
|
MAT4X4 = 380,
|
||||||
SAMPLER2DMSARRAY = 381,
|
DMAT2X2 = 381,
|
||||||
ISAMPLER2DMSARRAY = 382,
|
DMAT2X3 = 382,
|
||||||
USAMPLER2DMSARRAY = 383,
|
DMAT2X4 = 383,
|
||||||
SAMPLEREXTERNALOES = 384,
|
DMAT3X2 = 384,
|
||||||
SAMPLER = 385,
|
DMAT3X3 = 385,
|
||||||
SAMPLERSHADOW = 386,
|
DMAT3X4 = 386,
|
||||||
TEXTURE1D = 387,
|
DMAT4X2 = 387,
|
||||||
TEXTURE2D = 388,
|
DMAT4X3 = 388,
|
||||||
TEXTURE3D = 389,
|
DMAT4X4 = 389,
|
||||||
TEXTURECUBE = 390,
|
F16MAT2X2 = 390,
|
||||||
TEXTURE1DARRAY = 391,
|
F16MAT2X3 = 391,
|
||||||
TEXTURE2DARRAY = 392,
|
F16MAT2X4 = 392,
|
||||||
ITEXTURE1D = 393,
|
F16MAT3X2 = 393,
|
||||||
ITEXTURE2D = 394,
|
F16MAT3X3 = 394,
|
||||||
ITEXTURE3D = 395,
|
F16MAT3X4 = 395,
|
||||||
ITEXTURECUBE = 396,
|
F16MAT4X2 = 396,
|
||||||
ITEXTURE1DARRAY = 397,
|
F16MAT4X3 = 397,
|
||||||
ITEXTURE2DARRAY = 398,
|
F16MAT4X4 = 398,
|
||||||
UTEXTURE1D = 399,
|
F32MAT2X2 = 399,
|
||||||
UTEXTURE2D = 400,
|
F32MAT2X3 = 400,
|
||||||
UTEXTURE3D = 401,
|
F32MAT2X4 = 401,
|
||||||
UTEXTURECUBE = 402,
|
F32MAT3X2 = 402,
|
||||||
UTEXTURE1DARRAY = 403,
|
F32MAT3X3 = 403,
|
||||||
UTEXTURE2DARRAY = 404,
|
F32MAT3X4 = 404,
|
||||||
TEXTURE2DRECT = 405,
|
F32MAT4X2 = 405,
|
||||||
ITEXTURE2DRECT = 406,
|
F32MAT4X3 = 406,
|
||||||
UTEXTURE2DRECT = 407,
|
F32MAT4X4 = 407,
|
||||||
TEXTUREBUFFER = 408,
|
F64MAT2X2 = 408,
|
||||||
ITEXTUREBUFFER = 409,
|
F64MAT2X3 = 409,
|
||||||
UTEXTUREBUFFER = 410,
|
F64MAT2X4 = 410,
|
||||||
TEXTURECUBEARRAY = 411,
|
F64MAT3X2 = 411,
|
||||||
ITEXTURECUBEARRAY = 412,
|
F64MAT3X3 = 412,
|
||||||
UTEXTURECUBEARRAY = 413,
|
F64MAT3X4 = 413,
|
||||||
TEXTURE2DMS = 414,
|
F64MAT4X2 = 414,
|
||||||
ITEXTURE2DMS = 415,
|
F64MAT4X3 = 415,
|
||||||
UTEXTURE2DMS = 416,
|
F64MAT4X4 = 416,
|
||||||
TEXTURE2DMSARRAY = 417,
|
ATOMIC_UINT = 417,
|
||||||
ITEXTURE2DMSARRAY = 418,
|
SAMPLER1D = 418,
|
||||||
UTEXTURE2DMSARRAY = 419,
|
SAMPLER2D = 419,
|
||||||
SUBPASSINPUT = 420,
|
SAMPLER3D = 420,
|
||||||
SUBPASSINPUTMS = 421,
|
SAMPLERCUBE = 421,
|
||||||
ISUBPASSINPUT = 422,
|
SAMPLER1DSHADOW = 422,
|
||||||
ISUBPASSINPUTMS = 423,
|
SAMPLER2DSHADOW = 423,
|
||||||
USUBPASSINPUT = 424,
|
SAMPLERCUBESHADOW = 424,
|
||||||
USUBPASSINPUTMS = 425,
|
SAMPLER1DARRAY = 425,
|
||||||
IMAGE1D = 426,
|
SAMPLER2DARRAY = 426,
|
||||||
IIMAGE1D = 427,
|
SAMPLER1DARRAYSHADOW = 427,
|
||||||
UIMAGE1D = 428,
|
SAMPLER2DARRAYSHADOW = 428,
|
||||||
IMAGE2D = 429,
|
ISAMPLER1D = 429,
|
||||||
IIMAGE2D = 430,
|
ISAMPLER2D = 430,
|
||||||
UIMAGE2D = 431,
|
ISAMPLER3D = 431,
|
||||||
IMAGE3D = 432,
|
ISAMPLERCUBE = 432,
|
||||||
IIMAGE3D = 433,
|
ISAMPLER1DARRAY = 433,
|
||||||
UIMAGE3D = 434,
|
ISAMPLER2DARRAY = 434,
|
||||||
IMAGE2DRECT = 435,
|
USAMPLER1D = 435,
|
||||||
IIMAGE2DRECT = 436,
|
USAMPLER2D = 436,
|
||||||
UIMAGE2DRECT = 437,
|
USAMPLER3D = 437,
|
||||||
IMAGECUBE = 438,
|
USAMPLERCUBE = 438,
|
||||||
IIMAGECUBE = 439,
|
USAMPLER1DARRAY = 439,
|
||||||
UIMAGECUBE = 440,
|
USAMPLER2DARRAY = 440,
|
||||||
IMAGEBUFFER = 441,
|
SAMPLER2DRECT = 441,
|
||||||
IIMAGEBUFFER = 442,
|
SAMPLER2DRECTSHADOW = 442,
|
||||||
UIMAGEBUFFER = 443,
|
ISAMPLER2DRECT = 443,
|
||||||
IMAGE1DARRAY = 444,
|
USAMPLER2DRECT = 444,
|
||||||
IIMAGE1DARRAY = 445,
|
SAMPLERBUFFER = 445,
|
||||||
UIMAGE1DARRAY = 446,
|
ISAMPLERBUFFER = 446,
|
||||||
IMAGE2DARRAY = 447,
|
USAMPLERBUFFER = 447,
|
||||||
IIMAGE2DARRAY = 448,
|
SAMPLERCUBEARRAY = 448,
|
||||||
UIMAGE2DARRAY = 449,
|
SAMPLERCUBEARRAYSHADOW = 449,
|
||||||
IMAGECUBEARRAY = 450,
|
ISAMPLERCUBEARRAY = 450,
|
||||||
IIMAGECUBEARRAY = 451,
|
USAMPLERCUBEARRAY = 451,
|
||||||
UIMAGECUBEARRAY = 452,
|
SAMPLER2DMS = 452,
|
||||||
IMAGE2DMS = 453,
|
ISAMPLER2DMS = 453,
|
||||||
IIMAGE2DMS = 454,
|
USAMPLER2DMS = 454,
|
||||||
UIMAGE2DMS = 455,
|
SAMPLER2DMSARRAY = 455,
|
||||||
IMAGE2DMSARRAY = 456,
|
ISAMPLER2DMSARRAY = 456,
|
||||||
IIMAGE2DMSARRAY = 457,
|
USAMPLER2DMSARRAY = 457,
|
||||||
UIMAGE2DMSARRAY = 458,
|
SAMPLEREXTERNALOES = 458,
|
||||||
STRUCT = 459,
|
F16SAMPLER1D = 459,
|
||||||
VOID = 460,
|
F16SAMPLER2D = 460,
|
||||||
WHILE = 461,
|
F16SAMPLER3D = 461,
|
||||||
IDENTIFIER = 462,
|
F16SAMPLER2DRECT = 462,
|
||||||
TYPE_NAME = 463,
|
F16SAMPLERCUBE = 463,
|
||||||
FLOATCONSTANT = 464,
|
F16SAMPLER1DARRAY = 464,
|
||||||
DOUBLECONSTANT = 465,
|
F16SAMPLER2DARRAY = 465,
|
||||||
INTCONSTANT = 466,
|
F16SAMPLERCUBEARRAY = 466,
|
||||||
UINTCONSTANT = 467,
|
F16SAMPLERBUFFER = 467,
|
||||||
INT64CONSTANT = 468,
|
F16SAMPLER2DMS = 468,
|
||||||
UINT64CONSTANT = 469,
|
F16SAMPLER2DMSARRAY = 469,
|
||||||
BOOLCONSTANT = 470,
|
F16SAMPLER1DSHADOW = 470,
|
||||||
LEFT_OP = 471,
|
F16SAMPLER2DSHADOW = 471,
|
||||||
RIGHT_OP = 472,
|
F16SAMPLER1DARRAYSHADOW = 472,
|
||||||
INC_OP = 473,
|
F16SAMPLER2DARRAYSHADOW = 473,
|
||||||
DEC_OP = 474,
|
F16SAMPLER2DRECTSHADOW = 474,
|
||||||
LE_OP = 475,
|
F16SAMPLERCUBESHADOW = 475,
|
||||||
GE_OP = 476,
|
F16SAMPLERCUBEARRAYSHADOW = 476,
|
||||||
EQ_OP = 477,
|
SAMPLER = 477,
|
||||||
NE_OP = 478,
|
SAMPLERSHADOW = 478,
|
||||||
AND_OP = 479,
|
TEXTURE1D = 479,
|
||||||
OR_OP = 480,
|
TEXTURE2D = 480,
|
||||||
XOR_OP = 481,
|
TEXTURE3D = 481,
|
||||||
MUL_ASSIGN = 482,
|
TEXTURECUBE = 482,
|
||||||
DIV_ASSIGN = 483,
|
TEXTURE1DARRAY = 483,
|
||||||
ADD_ASSIGN = 484,
|
TEXTURE2DARRAY = 484,
|
||||||
MOD_ASSIGN = 485,
|
ITEXTURE1D = 485,
|
||||||
LEFT_ASSIGN = 486,
|
ITEXTURE2D = 486,
|
||||||
RIGHT_ASSIGN = 487,
|
ITEXTURE3D = 487,
|
||||||
AND_ASSIGN = 488,
|
ITEXTURECUBE = 488,
|
||||||
XOR_ASSIGN = 489,
|
ITEXTURE1DARRAY = 489,
|
||||||
OR_ASSIGN = 490,
|
ITEXTURE2DARRAY = 490,
|
||||||
SUB_ASSIGN = 491,
|
UTEXTURE1D = 491,
|
||||||
LEFT_PAREN = 492,
|
UTEXTURE2D = 492,
|
||||||
RIGHT_PAREN = 493,
|
UTEXTURE3D = 493,
|
||||||
LEFT_BRACKET = 494,
|
UTEXTURECUBE = 494,
|
||||||
RIGHT_BRACKET = 495,
|
UTEXTURE1DARRAY = 495,
|
||||||
LEFT_BRACE = 496,
|
UTEXTURE2DARRAY = 496,
|
||||||
RIGHT_BRACE = 497,
|
TEXTURE2DRECT = 497,
|
||||||
DOT = 498,
|
ITEXTURE2DRECT = 498,
|
||||||
COMMA = 499,
|
UTEXTURE2DRECT = 499,
|
||||||
COLON = 500,
|
TEXTUREBUFFER = 500,
|
||||||
EQUAL = 501,
|
ITEXTUREBUFFER = 501,
|
||||||
SEMICOLON = 502,
|
UTEXTUREBUFFER = 502,
|
||||||
BANG = 503,
|
TEXTURECUBEARRAY = 503,
|
||||||
DASH = 504,
|
ITEXTURECUBEARRAY = 504,
|
||||||
TILDE = 505,
|
UTEXTURECUBEARRAY = 505,
|
||||||
PLUS = 506,
|
TEXTURE2DMS = 506,
|
||||||
STAR = 507,
|
ITEXTURE2DMS = 507,
|
||||||
SLASH = 508,
|
UTEXTURE2DMS = 508,
|
||||||
PERCENT = 509,
|
TEXTURE2DMSARRAY = 509,
|
||||||
LEFT_ANGLE = 510,
|
ITEXTURE2DMSARRAY = 510,
|
||||||
RIGHT_ANGLE = 511,
|
UTEXTURE2DMSARRAY = 511,
|
||||||
VERTICAL_BAR = 512,
|
F16TEXTURE1D = 512,
|
||||||
CARET = 513,
|
F16TEXTURE2D = 513,
|
||||||
AMPERSAND = 514,
|
F16TEXTURE3D = 514,
|
||||||
QUESTION = 515,
|
F16TEXTURE2DRECT = 515,
|
||||||
INVARIANT = 516,
|
F16TEXTURECUBE = 516,
|
||||||
PRECISE = 517,
|
F16TEXTURE1DARRAY = 517,
|
||||||
HIGH_PRECISION = 518,
|
F16TEXTURE2DARRAY = 518,
|
||||||
MEDIUM_PRECISION = 519,
|
F16TEXTURECUBEARRAY = 519,
|
||||||
LOW_PRECISION = 520,
|
F16TEXTUREBUFFER = 520,
|
||||||
PRECISION = 521,
|
F16TEXTURE2DMS = 521,
|
||||||
PACKED = 522,
|
F16TEXTURE2DMSARRAY = 522,
|
||||||
RESOURCE = 523,
|
SUBPASSINPUT = 523,
|
||||||
SUPERP = 524
|
SUBPASSINPUTMS = 524,
|
||||||
|
ISUBPASSINPUT = 525,
|
||||||
|
ISUBPASSINPUTMS = 526,
|
||||||
|
USUBPASSINPUT = 527,
|
||||||
|
USUBPASSINPUTMS = 528,
|
||||||
|
F16SUBPASSINPUT = 529,
|
||||||
|
F16SUBPASSINPUTMS = 530,
|
||||||
|
IMAGE1D = 531,
|
||||||
|
IIMAGE1D = 532,
|
||||||
|
UIMAGE1D = 533,
|
||||||
|
IMAGE2D = 534,
|
||||||
|
IIMAGE2D = 535,
|
||||||
|
UIMAGE2D = 536,
|
||||||
|
IMAGE3D = 537,
|
||||||
|
IIMAGE3D = 538,
|
||||||
|
UIMAGE3D = 539,
|
||||||
|
IMAGE2DRECT = 540,
|
||||||
|
IIMAGE2DRECT = 541,
|
||||||
|
UIMAGE2DRECT = 542,
|
||||||
|
IMAGECUBE = 543,
|
||||||
|
IIMAGECUBE = 544,
|
||||||
|
UIMAGECUBE = 545,
|
||||||
|
IMAGEBUFFER = 546,
|
||||||
|
IIMAGEBUFFER = 547,
|
||||||
|
UIMAGEBUFFER = 548,
|
||||||
|
IMAGE1DARRAY = 549,
|
||||||
|
IIMAGE1DARRAY = 550,
|
||||||
|
UIMAGE1DARRAY = 551,
|
||||||
|
IMAGE2DARRAY = 552,
|
||||||
|
IIMAGE2DARRAY = 553,
|
||||||
|
UIMAGE2DARRAY = 554,
|
||||||
|
IMAGECUBEARRAY = 555,
|
||||||
|
IIMAGECUBEARRAY = 556,
|
||||||
|
UIMAGECUBEARRAY = 557,
|
||||||
|
IMAGE2DMS = 558,
|
||||||
|
IIMAGE2DMS = 559,
|
||||||
|
UIMAGE2DMS = 560,
|
||||||
|
IMAGE2DMSARRAY = 561,
|
||||||
|
IIMAGE2DMSARRAY = 562,
|
||||||
|
UIMAGE2DMSARRAY = 563,
|
||||||
|
F16IMAGE1D = 564,
|
||||||
|
F16IMAGE2D = 565,
|
||||||
|
F16IMAGE3D = 566,
|
||||||
|
F16IMAGE2DRECT = 567,
|
||||||
|
F16IMAGECUBE = 568,
|
||||||
|
F16IMAGE1DARRAY = 569,
|
||||||
|
F16IMAGE2DARRAY = 570,
|
||||||
|
F16IMAGECUBEARRAY = 571,
|
||||||
|
F16IMAGEBUFFER = 572,
|
||||||
|
F16IMAGE2DMS = 573,
|
||||||
|
F16IMAGE2DMSARRAY = 574,
|
||||||
|
STRUCT = 575,
|
||||||
|
VOID = 576,
|
||||||
|
WHILE = 577,
|
||||||
|
IDENTIFIER = 578,
|
||||||
|
TYPE_NAME = 579,
|
||||||
|
FLOATCONSTANT = 580,
|
||||||
|
DOUBLECONSTANT = 581,
|
||||||
|
INT16CONSTANT = 582,
|
||||||
|
UINT16CONSTANT = 583,
|
||||||
|
INT32CONSTANT = 584,
|
||||||
|
UINT32CONSTANT = 585,
|
||||||
|
INTCONSTANT = 586,
|
||||||
|
UINTCONSTANT = 587,
|
||||||
|
INT64CONSTANT = 588,
|
||||||
|
UINT64CONSTANT = 589,
|
||||||
|
BOOLCONSTANT = 590,
|
||||||
|
FLOAT16CONSTANT = 591,
|
||||||
|
LEFT_OP = 592,
|
||||||
|
RIGHT_OP = 593,
|
||||||
|
INC_OP = 594,
|
||||||
|
DEC_OP = 595,
|
||||||
|
LE_OP = 596,
|
||||||
|
GE_OP = 597,
|
||||||
|
EQ_OP = 598,
|
||||||
|
NE_OP = 599,
|
||||||
|
AND_OP = 600,
|
||||||
|
OR_OP = 601,
|
||||||
|
XOR_OP = 602,
|
||||||
|
MUL_ASSIGN = 603,
|
||||||
|
DIV_ASSIGN = 604,
|
||||||
|
ADD_ASSIGN = 605,
|
||||||
|
MOD_ASSIGN = 606,
|
||||||
|
LEFT_ASSIGN = 607,
|
||||||
|
RIGHT_ASSIGN = 608,
|
||||||
|
AND_ASSIGN = 609,
|
||||||
|
XOR_ASSIGN = 610,
|
||||||
|
OR_ASSIGN = 611,
|
||||||
|
SUB_ASSIGN = 612,
|
||||||
|
LEFT_PAREN = 613,
|
||||||
|
RIGHT_PAREN = 614,
|
||||||
|
LEFT_BRACKET = 615,
|
||||||
|
RIGHT_BRACKET = 616,
|
||||||
|
LEFT_BRACE = 617,
|
||||||
|
RIGHT_BRACE = 618,
|
||||||
|
DOT = 619,
|
||||||
|
COMMA = 620,
|
||||||
|
COLON = 621,
|
||||||
|
EQUAL = 622,
|
||||||
|
SEMICOLON = 623,
|
||||||
|
BANG = 624,
|
||||||
|
DASH = 625,
|
||||||
|
TILDE = 626,
|
||||||
|
PLUS = 627,
|
||||||
|
STAR = 628,
|
||||||
|
SLASH = 629,
|
||||||
|
PERCENT = 630,
|
||||||
|
LEFT_ANGLE = 631,
|
||||||
|
RIGHT_ANGLE = 632,
|
||||||
|
VERTICAL_BAR = 633,
|
||||||
|
CARET = 634,
|
||||||
|
AMPERSAND = 635,
|
||||||
|
QUESTION = 636,
|
||||||
|
INVARIANT = 637,
|
||||||
|
PRECISE = 638,
|
||||||
|
HIGH_PRECISION = 639,
|
||||||
|
MEDIUM_PRECISION = 640,
|
||||||
|
LOW_PRECISION = 641,
|
||||||
|
PRECISION = 642,
|
||||||
|
PACKED = 643,
|
||||||
|
RESOURCE = 644,
|
||||||
|
SUPERP = 645
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Value type. */
|
/* Value type. */
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
|
typedef union YYSTYPE YYSTYPE;
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 66 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
#line 70 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
glslang::TSourceLoc loc;
|
glslang::TSourceLoc loc;
|
||||||
|
@ -342,6 +463,7 @@ union YYSTYPE
|
||||||
TIntermNode* intermNode;
|
TIntermNode* intermNode;
|
||||||
glslang::TIntermNodePair nodePair;
|
glslang::TIntermNodePair nodePair;
|
||||||
glslang::TIntermTyped* intermTypedNode;
|
glslang::TIntermTyped* intermTypedNode;
|
||||||
|
glslang::TAttributes* attributes;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
glslang::TPublicType type;
|
glslang::TPublicType type;
|
||||||
|
@ -354,10 +476,8 @@ union YYSTYPE
|
||||||
};
|
};
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
#line 358 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
#line 480 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
756
Externals/glslang/glslang/MachineIndependent/intermOut.cpp
vendored
Normal file → Executable file
756
Externals/glslang/glslang/MachineIndependent/intermOut.cpp
vendored
Normal file → Executable file
|
@ -1,12 +1,13 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2012-2016 LunarG, Inc.
|
// Copyright (C) 2012-2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -20,40 +21,56 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
#include "../Include/InfoSink.h"
|
#include "../Include/InfoSink.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <float.h>
|
#include <cfloat>
|
||||||
#elif defined __ANDROID__ || defined __linux__ || __MINGW32__ || __MINGW64__
|
|
||||||
#include <cmath>
|
|
||||||
#else
|
#else
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool is_positive_infinity(double x) {
|
bool IsInfinity(double x) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return _fpclass(x) == _FPCLASS_PINF;
|
switch (_fpclass(x)) {
|
||||||
#elif defined __ANDROID__ || defined __linux__ || __MINGW32__ || __MINGW64__
|
case _FPCLASS_NINF:
|
||||||
return std::isinf(x) && (x >= 0);
|
case _FPCLASS_PINF:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
return isinf(x) && (x >= 0);
|
return std::isinf(x);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsNan(double x) {
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
switch (_fpclass(x)) {
|
||||||
|
case _FPCLASS_SNAN:
|
||||||
|
case _FPCLASS_QNAN:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return std::isnan(x);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +93,13 @@ namespace glslang {
|
||||||
//
|
//
|
||||||
class TOutputTraverser : public TIntermTraverser {
|
class TOutputTraverser : public TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TOutputTraverser(TInfoSink& i) : infoSink(i) { }
|
TOutputTraverser(TInfoSink& i) : infoSink(i), extraOutput(NoExtraOutput) { }
|
||||||
|
|
||||||
|
enum EExtraOutput {
|
||||||
|
NoExtraOutput,
|
||||||
|
BinaryDoubleOutput
|
||||||
|
};
|
||||||
|
void setDoubleOutput(EExtraOutput extra) { extraOutput = extra; }
|
||||||
|
|
||||||
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
||||||
virtual bool visitUnary(TVisit, TIntermUnary* node);
|
virtual bool visitUnary(TVisit, TIntermUnary* node);
|
||||||
|
@ -92,6 +115,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
TOutputTraverser(TOutputTraverser&);
|
TOutputTraverser(TOutputTraverser&);
|
||||||
TOutputTraverser& operator=(TOutputTraverser&);
|
TOutputTraverser& operator=(TOutputTraverser&);
|
||||||
|
|
||||||
|
EExtraOutput extraOutput;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -150,6 +175,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||||
out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
|
out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
|
||||||
out.debug << ": direct index for structure"; break;
|
out.debug << ": direct index for structure"; break;
|
||||||
case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
|
case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
|
||||||
|
case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
|
||||||
|
|
||||||
case EOpAdd: out.debug << "add"; break;
|
case EOpAdd: out.debug << "add"; break;
|
||||||
case EOpSub: out.debug << "subtract"; break;
|
case EOpSub: out.debug << "subtract"; break;
|
||||||
|
@ -167,6 +193,8 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||||
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
|
||||||
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
|
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
|
||||||
case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
|
case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
|
||||||
|
case EOpVectorEqual: out.debug << "Equal"; break;
|
||||||
|
case EOpVectorNotEqual: out.debug << "NotEqual"; break;
|
||||||
|
|
||||||
case EOpVectorTimesScalar: out.debug << "vector-scale"; break;
|
case EOpVectorTimesScalar: out.debug << "vector-scale"; break;
|
||||||
case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break;
|
case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break;
|
||||||
|
@ -177,6 +205,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||||
case EOpLogicalOr: out.debug << "logical-or"; break;
|
case EOpLogicalOr: out.debug << "logical-or"; break;
|
||||||
case EOpLogicalXor: out.debug << "logical-xor"; break;
|
case EOpLogicalXor: out.debug << "logical-xor"; break;
|
||||||
case EOpLogicalAnd: out.debug << "logical-and"; break;
|
case EOpLogicalAnd: out.debug << "logical-and"; break;
|
||||||
|
|
||||||
default: out.debug << "<unknown op>";
|
default: out.debug << "<unknown op>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,48 +233,192 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
case EOpPreIncrement: out.debug << "Pre-Increment"; break;
|
case EOpPreIncrement: out.debug << "Pre-Increment"; break;
|
||||||
case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
|
case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
|
||||||
|
|
||||||
|
// * -> bool
|
||||||
|
case EOpConvInt8ToBool: out.debug << "Convert int8_t to bool"; break;
|
||||||
|
case EOpConvUint8ToBool: out.debug << "Convert uint8_t to bool"; break;
|
||||||
|
case EOpConvInt16ToBool: out.debug << "Convert int16_t to bool"; break;
|
||||||
|
case EOpConvUint16ToBool: out.debug << "Convert uint16_t to bool";break;
|
||||||
case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
|
case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
|
||||||
case EOpConvUintToBool: out.debug << "Convert uint to bool"; break;
|
case EOpConvUintToBool: out.debug << "Convert uint to bool"; break;
|
||||||
case EOpConvFloatToBool: out.debug << "Convert float to bool"; break;
|
|
||||||
case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break;
|
|
||||||
case EOpConvInt64ToBool: out.debug << "Convert int64 to bool"; break;
|
case EOpConvInt64ToBool: out.debug << "Convert int64 to bool"; break;
|
||||||
case EOpConvUint64ToBool: out.debug << "Convert uint64 to bool"; break;
|
case EOpConvUint64ToBool: out.debug << "Convert uint64 to bool"; break;
|
||||||
case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
|
case EOpConvFloat16ToBool: out.debug << "Convert float16_t to bool"; break;
|
||||||
case EOpConvUintToFloat: out.debug << "Convert uint to float"; break;
|
case EOpConvFloatToBool: out.debug << "Convert float to bool"; break;
|
||||||
case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break;
|
case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break;
|
||||||
case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break;
|
|
||||||
case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break;
|
// bool -> *
|
||||||
case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break;
|
case EOpConvBoolToInt8: out.debug << "Convert bool to int8_t"; break;
|
||||||
case EOpConvUintToInt: out.debug << "Convert uint to int"; break;
|
case EOpConvBoolToUint8: out.debug << "Convert bool to uint8_t"; break;
|
||||||
case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
|
case EOpConvBoolToInt16: out.debug << "Convert bool to in16t_t"; break;
|
||||||
case EOpConvDoubleToInt: out.debug << "Convert double to int"; break;
|
case EOpConvBoolToUint16: out.debug << "Convert bool to uint16_t";break;
|
||||||
case EOpConvBoolToInt: out.debug << "Convert bool to int"; break;
|
case EOpConvBoolToInt: out.debug << "Convert bool to int" ; break;
|
||||||
case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break;
|
|
||||||
case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break;
|
|
||||||
case EOpConvIntToUint: out.debug << "Convert int to uint"; break;
|
|
||||||
case EOpConvFloatToUint: out.debug << "Convert float to uint"; break;
|
|
||||||
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
|
|
||||||
case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break;
|
case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break;
|
||||||
case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break;
|
|
||||||
case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break;
|
|
||||||
case EOpConvIntToDouble: out.debug << "Convert int to double"; break;
|
|
||||||
case EOpConvUintToDouble: out.debug << "Convert uint to double"; break;
|
|
||||||
case EOpConvFloatToDouble: out.debug << "Convert float to double"; break;
|
|
||||||
case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break;
|
|
||||||
case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break;
|
|
||||||
case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break;
|
|
||||||
case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break;
|
case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break;
|
||||||
|
case EOpConvBoolToUint64: out.debug << "Convert bool to uint64";break;
|
||||||
|
case EOpConvBoolToFloat16: out.debug << "Convert bool to float16_t"; break;
|
||||||
|
case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break;
|
||||||
|
case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break;
|
||||||
|
|
||||||
|
// int8_t -> (u)int*
|
||||||
|
case EOpConvInt8ToInt16: out.debug << "Convert int8_t to int16_t";break;
|
||||||
|
case EOpConvInt8ToInt: out.debug << "Convert int8_t to int"; break;
|
||||||
|
case EOpConvInt8ToInt64: out.debug << "Convert int8_t to int64"; break;
|
||||||
|
case EOpConvInt8ToUint8: out.debug << "Convert int8_t to uint8_t";break;
|
||||||
|
case EOpConvInt8ToUint16: out.debug << "Convert int8_t to uint16_t";break;
|
||||||
|
case EOpConvInt8ToUint: out.debug << "Convert int8_t to uint"; break;
|
||||||
|
case EOpConvInt8ToUint64: out.debug << "Convert int8_t to uint64"; break;
|
||||||
|
|
||||||
|
// uint8_t -> (u)int*
|
||||||
|
case EOpConvUint8ToInt8: out.debug << "Convert uint8_t to int8_t";break;
|
||||||
|
case EOpConvUint8ToInt16: out.debug << "Convert uint8_t to int16_t";break;
|
||||||
|
case EOpConvUint8ToInt: out.debug << "Convert uint8_t to int"; break;
|
||||||
|
case EOpConvUint8ToInt64: out.debug << "Convert uint8_t to int64"; break;
|
||||||
|
case EOpConvUint8ToUint16: out.debug << "Convert uint8_t to uint16_t";break;
|
||||||
|
case EOpConvUint8ToUint: out.debug << "Convert uint8_t to uint"; break;
|
||||||
|
case EOpConvUint8ToUint64: out.debug << "Convert uint8_t to uint64"; break;
|
||||||
|
|
||||||
|
// int8_t -> float*
|
||||||
|
case EOpConvInt8ToFloat16: out.debug << "Convert int8_t to float16_t";break;
|
||||||
|
case EOpConvInt8ToFloat: out.debug << "Convert int8_t to float"; break;
|
||||||
|
case EOpConvInt8ToDouble: out.debug << "Convert int8_t to double"; break;
|
||||||
|
|
||||||
|
// uint8_t -> float*
|
||||||
|
case EOpConvUint8ToFloat16: out.debug << "Convert uint8_t to float16_t";break;
|
||||||
|
case EOpConvUint8ToFloat: out.debug << "Convert uint8_t to float"; break;
|
||||||
|
case EOpConvUint8ToDouble: out.debug << "Convert uint8_t to double"; break;
|
||||||
|
|
||||||
|
// int16_t -> (u)int*
|
||||||
|
case EOpConvInt16ToInt8: out.debug << "Convert int16_t to int8_t";break;
|
||||||
|
case EOpConvInt16ToInt: out.debug << "Convert int16_t to int"; break;
|
||||||
|
case EOpConvInt16ToInt64: out.debug << "Convert int16_t to int64"; break;
|
||||||
|
case EOpConvInt16ToUint8: out.debug << "Convert int16_t to uint8_t";break;
|
||||||
|
case EOpConvInt16ToUint16: out.debug << "Convert int16_t to uint16_t";break;
|
||||||
|
case EOpConvInt16ToUint: out.debug << "Convert int16_t to uint"; break;
|
||||||
|
case EOpConvInt16ToUint64: out.debug << "Convert int16_t to uint64"; break;
|
||||||
|
|
||||||
|
// int16_t -> float*
|
||||||
|
case EOpConvInt16ToFloat16: out.debug << "Convert int16_t to float16_t";break;
|
||||||
|
case EOpConvInt16ToFloat: out.debug << "Convert int16_t to float"; break;
|
||||||
|
case EOpConvInt16ToDouble: out.debug << "Convert int16_t to double"; break;
|
||||||
|
|
||||||
|
// uint16_t -> (u)int*
|
||||||
|
case EOpConvUint16ToInt8: out.debug << "Convert uint16_t to int8_t";break;
|
||||||
|
case EOpConvUint16ToInt16: out.debug << "Convert uint16_t to int16_t";break;
|
||||||
|
case EOpConvUint16ToInt: out.debug << "Convert uint16_t to int"; break;
|
||||||
|
case EOpConvUint16ToInt64: out.debug << "Convert uint16_t to int64"; break;
|
||||||
|
case EOpConvUint16ToUint8: out.debug << "Convert uint16_t to uint8_t";break;
|
||||||
|
case EOpConvUint16ToUint: out.debug << "Convert uint16_t to uint"; break;
|
||||||
|
case EOpConvUint16ToUint64: out.debug << "Convert uint16_t to uint64"; break;
|
||||||
|
|
||||||
|
// uint16_t -> float*
|
||||||
|
case EOpConvUint16ToFloat16: out.debug << "Convert uint16_t to float16_t";break;
|
||||||
|
case EOpConvUint16ToFloat: out.debug << "Convert uint16_t to float"; break;
|
||||||
|
case EOpConvUint16ToDouble: out.debug << "Convert uint16_t to double"; break;
|
||||||
|
|
||||||
|
// int32_t -> (u)int*
|
||||||
|
case EOpConvIntToInt8: out.debug << "Convert int to int8_t";break;
|
||||||
|
case EOpConvIntToInt16: out.debug << "Convert int to int16_t";break;
|
||||||
case EOpConvIntToInt64: out.debug << "Convert int to int64"; break;
|
case EOpConvIntToInt64: out.debug << "Convert int to int64"; break;
|
||||||
case EOpConvUintToInt64: out.debug << "Convert uint to int64"; break;
|
case EOpConvIntToUint8: out.debug << "Convert int to uint8_t";break;
|
||||||
case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break;
|
case EOpConvIntToUint16: out.debug << "Convert int to uint16_t";break;
|
||||||
case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break;
|
case EOpConvIntToUint: out.debug << "Convert int to uint"; break;
|
||||||
case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break;
|
|
||||||
case EOpConvBoolToUint64: out.debug << "Convert bool to uint64"; break;
|
|
||||||
case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break;
|
case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break;
|
||||||
|
|
||||||
|
// int32_t -> float*
|
||||||
|
case EOpConvIntToFloat16: out.debug << "Convert int to float16_t";break;
|
||||||
|
case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
|
||||||
|
case EOpConvIntToDouble: out.debug << "Convert int to double"; break;
|
||||||
|
|
||||||
|
// uint32_t -> (u)int*
|
||||||
|
case EOpConvUintToInt8: out.debug << "Convert uint to int8_t";break;
|
||||||
|
case EOpConvUintToInt16: out.debug << "Convert uint to int16_t";break;
|
||||||
|
case EOpConvUintToInt: out.debug << "Convert uint to int";break;
|
||||||
|
case EOpConvUintToInt64: out.debug << "Convert uint to int64"; break;
|
||||||
|
case EOpConvUintToUint8: out.debug << "Convert uint to uint8_t";break;
|
||||||
|
case EOpConvUintToUint16: out.debug << "Convert uint to uint16_t";break;
|
||||||
case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break;
|
case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break;
|
||||||
|
|
||||||
|
// uint32_t -> float*
|
||||||
|
case EOpConvUintToFloat16: out.debug << "Convert uint to float16_t";break;
|
||||||
|
case EOpConvUintToFloat: out.debug << "Convert uint to float"; break;
|
||||||
|
case EOpConvUintToDouble: out.debug << "Convert uint to double"; break;
|
||||||
|
|
||||||
|
// int64 -> (u)int*
|
||||||
|
case EOpConvInt64ToInt8: out.debug << "Convert int64 to int8_t"; break;
|
||||||
|
case EOpConvInt64ToInt16: out.debug << "Convert int64 to int16_t"; break;
|
||||||
|
case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break;
|
||||||
|
case EOpConvInt64ToUint8: out.debug << "Convert int64 to uint8_t";break;
|
||||||
|
case EOpConvInt64ToUint16: out.debug << "Convert int64 to uint16_t";break;
|
||||||
|
case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break;
|
||||||
|
case EOpConvInt64ToUint64: out.debug << "Convert int64 to uint64"; break;
|
||||||
|
|
||||||
|
// int64 -> float*
|
||||||
|
case EOpConvInt64ToFloat16: out.debug << "Convert int64 to float16_t";break;
|
||||||
|
case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break;
|
||||||
|
case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break;
|
||||||
|
|
||||||
|
// uint64 -> (u)int*
|
||||||
|
case EOpConvUint64ToInt8: out.debug << "Convert uint64 to int8_t";break;
|
||||||
|
case EOpConvUint64ToInt16: out.debug << "Convert uint64 to int16_t";break;
|
||||||
|
case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break;
|
||||||
|
case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break;
|
||||||
|
case EOpConvUint64ToUint8: out.debug << "Convert uint64 to uint8_t";break;
|
||||||
|
case EOpConvUint64ToUint16: out.debug << "Convert uint64 to uint16"; break;
|
||||||
|
case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break;
|
||||||
|
|
||||||
|
// uint64 -> float*
|
||||||
|
case EOpConvUint64ToFloat16: out.debug << "Convert uint64 to float16_t";break;
|
||||||
|
case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break;
|
||||||
|
case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break;
|
||||||
|
|
||||||
|
// float16_t -> int*
|
||||||
|
case EOpConvFloat16ToInt8: out.debug << "Convert float16_t to int8_t"; break;
|
||||||
|
case EOpConvFloat16ToInt16: out.debug << "Convert float16_t to int16_t"; break;
|
||||||
|
case EOpConvFloat16ToInt: out.debug << "Convert float16_t to int"; break;
|
||||||
|
case EOpConvFloat16ToInt64: out.debug << "Convert float16_t to int64"; break;
|
||||||
|
|
||||||
|
// float16_t -> uint*
|
||||||
|
case EOpConvFloat16ToUint8: out.debug << "Convert float16_t to uint8_t"; break;
|
||||||
|
case EOpConvFloat16ToUint16: out.debug << "Convert float16_t to uint16_t"; break;
|
||||||
|
case EOpConvFloat16ToUint: out.debug << "Convert float16_t to uint"; break;
|
||||||
|
case EOpConvFloat16ToUint64: out.debug << "Convert float16_t to uint64"; break;
|
||||||
|
|
||||||
|
// float16_t -> float*
|
||||||
|
case EOpConvFloat16ToFloat: out.debug << "Convert float16_t to float"; break;
|
||||||
|
case EOpConvFloat16ToDouble: out.debug << "Convert float16_t to double"; break;
|
||||||
|
|
||||||
|
// float32 -> float*
|
||||||
|
case EOpConvFloatToFloat16: out.debug << "Convert float to float16_t"; break;
|
||||||
|
case EOpConvFloatToDouble: out.debug << "Convert float to double"; break;
|
||||||
|
|
||||||
|
// float32_t -> int*
|
||||||
|
case EOpConvFloatToInt8: out.debug << "Convert float to int8_t"; break;
|
||||||
|
case EOpConvFloatToInt16: out.debug << "Convert float to int16_t"; break;
|
||||||
|
case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
|
||||||
|
case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break;
|
||||||
|
|
||||||
|
// float32_t -> uint*
|
||||||
|
case EOpConvFloatToUint8: out.debug << "Convert float to uint8_t"; break;
|
||||||
|
case EOpConvFloatToUint16: out.debug << "Convert float to uint16_t"; break;
|
||||||
|
case EOpConvFloatToUint: out.debug << "Convert float to uint"; break;
|
||||||
case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break;
|
case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break;
|
||||||
|
|
||||||
|
// double -> float*
|
||||||
|
case EOpConvDoubleToFloat16: out.debug << "Convert double to float16_t"; break;
|
||||||
|
case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break;
|
||||||
|
|
||||||
|
// double -> int*
|
||||||
|
case EOpConvDoubleToInt8: out.debug << "Convert double to int8_t"; break;
|
||||||
|
case EOpConvDoubleToInt16: out.debug << "Convert double to int16_t"; break;
|
||||||
|
case EOpConvDoubleToInt: out.debug << "Convert double to int"; break;
|
||||||
|
case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break;
|
||||||
|
|
||||||
|
// float32_t -> uint*
|
||||||
|
case EOpConvDoubleToUint8: out.debug << "Convert double to uint8_t"; break;
|
||||||
|
case EOpConvDoubleToUint16: out.debug << "Convert double to uint16_t"; break;
|
||||||
|
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
|
||||||
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
|
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
|
||||||
case EOpConvInt64ToUint64: out.debug << "Convert uint64 to uint64"; break;
|
|
||||||
|
|
||||||
case EOpRadians: out.debug << "radians"; break;
|
case EOpRadians: out.debug << "radians"; break;
|
||||||
case EOpDegrees: out.debug << "degrees"; break;
|
case EOpDegrees: out.debug << "degrees"; break;
|
||||||
|
@ -289,12 +462,23 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
|
case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
|
||||||
case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break;
|
case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break;
|
||||||
case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
|
case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
|
||||||
|
case EOpFloat16BitsToInt16: out.debug << "float16BitsToInt16"; break;
|
||||||
|
case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break;
|
||||||
|
case EOpInt16BitsToFloat16: out.debug << "int16BitsToFloat16"; break;
|
||||||
|
case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break;
|
||||||
|
|
||||||
case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break;
|
case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break;
|
||||||
case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break;
|
case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break;
|
||||||
case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break;
|
case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break;
|
||||||
case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16"; break;
|
case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16"; break;
|
||||||
case EOpPackHalf2x16: out.debug << "packHalf2x16"; break;
|
case EOpPackHalf2x16: out.debug << "packHalf2x16"; break;
|
||||||
case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16"; break;
|
case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16"; break;
|
||||||
|
case EOpPack16: out.debug << "pack16"; break;
|
||||||
|
case EOpPack32: out.debug << "pack32"; break;
|
||||||
|
case EOpPack64: out.debug << "pack64"; break;
|
||||||
|
case EOpUnpack32: out.debug << "unpack32"; break;
|
||||||
|
case EOpUnpack16: out.debug << "unpack16"; break;
|
||||||
|
case EOpUnpack8: out.debug << "unpack8"; break;
|
||||||
|
|
||||||
case EOpPackSnorm4x8: out.debug << "PackSnorm4x8"; break;
|
case EOpPackSnorm4x8: out.debug << "PackSnorm4x8"; break;
|
||||||
case EOpUnpackSnorm4x8: out.debug << "UnpackSnorm4x8"; break;
|
case EOpUnpackSnorm4x8: out.debug << "UnpackSnorm4x8"; break;
|
||||||
|
@ -308,6 +492,18 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
case EOpPackUint2x32: out.debug << "packUint2x32"; break;
|
case EOpPackUint2x32: out.debug << "packUint2x32"; break;
|
||||||
case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break;
|
case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break;
|
||||||
|
|
||||||
|
case EOpPackInt2x16: out.debug << "packInt2x16"; break;
|
||||||
|
case EOpUnpackInt2x16: out.debug << "unpackInt2x16"; break;
|
||||||
|
case EOpPackUint2x16: out.debug << "packUint2x16"; break;
|
||||||
|
case EOpUnpackUint2x16: out.debug << "unpackUint2x16"; break;
|
||||||
|
|
||||||
|
case EOpPackInt4x16: out.debug << "packInt4x16"; break;
|
||||||
|
case EOpUnpackInt4x16: out.debug << "unpackInt4x16"; break;
|
||||||
|
case EOpPackUint4x16: out.debug << "packUint4x16"; break;
|
||||||
|
case EOpUnpackUint4x16: out.debug << "unpackUint4x16"; break;
|
||||||
|
case EOpPackFloat2x16: out.debug << "packFloat2x16"; break;
|
||||||
|
case EOpUnpackFloat2x16: out.debug << "unpackFloat2x16"; break;
|
||||||
|
|
||||||
case EOpLength: out.debug << "length"; break;
|
case EOpLength: out.debug << "length"; break;
|
||||||
case EOpNormalize: out.debug << "normalize"; break;
|
case EOpNormalize: out.debug << "normalize"; break;
|
||||||
case EOpDPdx: out.debug << "dPdx"; break;
|
case EOpDPdx: out.debug << "dPdx"; break;
|
||||||
|
@ -355,16 +551,129 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||||
|
|
||||||
case EOpBallot: out.debug << "ballot"; break;
|
case EOpBallot: out.debug << "ballot"; break;
|
||||||
case EOpReadFirstInvocation: out.debug << "readFirstInvocation"; break;
|
case EOpReadFirstInvocation: out.debug << "readFirstInvocation"; break;
|
||||||
|
|
||||||
case EOpAnyInvocation: out.debug << "anyInvocation"; break;
|
case EOpAnyInvocation: out.debug << "anyInvocation"; break;
|
||||||
case EOpAllInvocations: out.debug << "allInvocations"; break;
|
case EOpAllInvocations: out.debug << "allInvocations"; break;
|
||||||
case EOpAllInvocationsEqual: out.debug << "allInvocationsEqual"; break;
|
case EOpAllInvocationsEqual: out.debug << "allInvocationsEqual"; break;
|
||||||
|
|
||||||
|
case EOpSubgroupElect: out.debug << "subgroupElect"; break;
|
||||||
|
case EOpSubgroupAll: out.debug << "subgroupAll"; break;
|
||||||
|
case EOpSubgroupAny: out.debug << "subgroupAny"; break;
|
||||||
|
case EOpSubgroupAllEqual: out.debug << "subgroupAllEqual"; break;
|
||||||
|
case EOpSubgroupBroadcast: out.debug << "subgroupBroadcast"; break;
|
||||||
|
case EOpSubgroupBroadcastFirst: out.debug << "subgroupBroadcastFirst"; break;
|
||||||
|
case EOpSubgroupBallot: out.debug << "subgroupBallot"; break;
|
||||||
|
case EOpSubgroupInverseBallot: out.debug << "subgroupInverseBallot"; break;
|
||||||
|
case EOpSubgroupBallotBitExtract: out.debug << "subgroupBallotBitExtract"; break;
|
||||||
|
case EOpSubgroupBallotBitCount: out.debug << "subgroupBallotBitCount"; break;
|
||||||
|
case EOpSubgroupBallotInclusiveBitCount: out.debug << "subgroupBallotInclusiveBitCount"; break;
|
||||||
|
case EOpSubgroupBallotExclusiveBitCount: out.debug << "subgroupBallotExclusiveBitCount"; break;
|
||||||
|
case EOpSubgroupBallotFindLSB: out.debug << "subgroupBallotFindLSB"; break;
|
||||||
|
case EOpSubgroupBallotFindMSB: out.debug << "subgroupBallotFindMSB"; break;
|
||||||
|
case EOpSubgroupShuffle: out.debug << "subgroupShuffle"; break;
|
||||||
|
case EOpSubgroupShuffleXor: out.debug << "subgroupShuffleXor"; break;
|
||||||
|
case EOpSubgroupShuffleUp: out.debug << "subgroupShuffleUp"; break;
|
||||||
|
case EOpSubgroupShuffleDown: out.debug << "subgroupShuffleDown"; break;
|
||||||
|
case EOpSubgroupAdd: out.debug << "subgroupAdd"; break;
|
||||||
|
case EOpSubgroupMul: out.debug << "subgroupMul"; break;
|
||||||
|
case EOpSubgroupMin: out.debug << "subgroupMin"; break;
|
||||||
|
case EOpSubgroupMax: out.debug << "subgroupMax"; break;
|
||||||
|
case EOpSubgroupAnd: out.debug << "subgroupAnd"; break;
|
||||||
|
case EOpSubgroupOr: out.debug << "subgroupOr"; break;
|
||||||
|
case EOpSubgroupXor: out.debug << "subgroupXor"; break;
|
||||||
|
case EOpSubgroupInclusiveAdd: out.debug << "subgroupInclusiveAdd"; break;
|
||||||
|
case EOpSubgroupInclusiveMul: out.debug << "subgroupInclusiveMul"; break;
|
||||||
|
case EOpSubgroupInclusiveMin: out.debug << "subgroupInclusiveMin"; break;
|
||||||
|
case EOpSubgroupInclusiveMax: out.debug << "subgroupInclusiveMax"; break;
|
||||||
|
case EOpSubgroupInclusiveAnd: out.debug << "subgroupInclusiveAnd"; break;
|
||||||
|
case EOpSubgroupInclusiveOr: out.debug << "subgroupInclusiveOr"; break;
|
||||||
|
case EOpSubgroupInclusiveXor: out.debug << "subgroupInclusiveXor"; break;
|
||||||
|
case EOpSubgroupExclusiveAdd: out.debug << "subgroupExclusiveAdd"; break;
|
||||||
|
case EOpSubgroupExclusiveMul: out.debug << "subgroupExclusiveMul"; break;
|
||||||
|
case EOpSubgroupExclusiveMin: out.debug << "subgroupExclusiveMin"; break;
|
||||||
|
case EOpSubgroupExclusiveMax: out.debug << "subgroupExclusiveMax"; break;
|
||||||
|
case EOpSubgroupExclusiveAnd: out.debug << "subgroupExclusiveAnd"; break;
|
||||||
|
case EOpSubgroupExclusiveOr: out.debug << "subgroupExclusiveOr"; break;
|
||||||
|
case EOpSubgroupExclusiveXor: out.debug << "subgroupExclusiveXor"; break;
|
||||||
|
case EOpSubgroupClusteredAdd: out.debug << "subgroupClusteredAdd"; break;
|
||||||
|
case EOpSubgroupClusteredMul: out.debug << "subgroupClusteredMul"; break;
|
||||||
|
case EOpSubgroupClusteredMin: out.debug << "subgroupClusteredMin"; break;
|
||||||
|
case EOpSubgroupClusteredMax: out.debug << "subgroupClusteredMax"; break;
|
||||||
|
case EOpSubgroupClusteredAnd: out.debug << "subgroupClusteredAnd"; break;
|
||||||
|
case EOpSubgroupClusteredOr: out.debug << "subgroupClusteredOr"; break;
|
||||||
|
case EOpSubgroupClusteredXor: out.debug << "subgroupClusteredXor"; break;
|
||||||
|
case EOpSubgroupQuadBroadcast: out.debug << "subgroupQuadBroadcast"; break;
|
||||||
|
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
|
||||||
|
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
|
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
||||||
|
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
||||||
|
case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; break;
|
||||||
|
case EOpSubgroupPartitionedMin: out.debug << "subgroupPartitionedMinNV"; break;
|
||||||
|
case EOpSubgroupPartitionedMax: out.debug << "subgroupPartitionedMaxNV"; break;
|
||||||
|
case EOpSubgroupPartitionedAnd: out.debug << "subgroupPartitionedAndNV"; break;
|
||||||
|
case EOpSubgroupPartitionedOr: out.debug << "subgroupPartitionedOrNV"; break;
|
||||||
|
case EOpSubgroupPartitionedXor: out.debug << "subgroupPartitionedXorNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveAdd: out.debug << "subgroupPartitionedInclusiveAddNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveMul: out.debug << "subgroupPartitionedInclusiveMulNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveMin: out.debug << "subgroupPartitionedInclusiveMinNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveMax: out.debug << "subgroupPartitionedInclusiveMaxNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveAnd: out.debug << "subgroupPartitionedInclusiveAndNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveOr: out.debug << "subgroupPartitionedInclusiveOrNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveXor: out.debug << "subgroupPartitionedInclusiveXorNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveAdd: out.debug << "subgroupPartitionedExclusiveAddNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveMul: out.debug << "subgroupPartitionedExclusiveMulNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveMin: out.debug << "subgroupPartitionedExclusiveMinNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveMax: out.debug << "subgroupPartitionedExclusiveMaxNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpClip: out.debug << "clip"; break;
|
case EOpClip: out.debug << "clip"; break;
|
||||||
case EOpIsFinite: out.debug << "isfinite"; break;
|
case EOpIsFinite: out.debug << "isfinite"; break;
|
||||||
case EOpLog10: out.debug << "log10"; break;
|
case EOpLog10: out.debug << "log10"; break;
|
||||||
case EOpRcp: out.debug << "rcp"; break;
|
case EOpRcp: out.debug << "rcp"; break;
|
||||||
case EOpSaturate: out.debug << "saturate"; break;
|
case EOpSaturate: out.debug << "saturate"; break;
|
||||||
|
|
||||||
|
case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break;
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpMinInvocations: out.debug << "minInvocations"; break;
|
||||||
|
case EOpMaxInvocations: out.debug << "maxInvocations"; break;
|
||||||
|
case EOpAddInvocations: out.debug << "addInvocations"; break;
|
||||||
|
case EOpMinInvocationsNonUniform: out.debug << "minInvocationsNonUniform"; break;
|
||||||
|
case EOpMaxInvocationsNonUniform: out.debug << "maxInvocationsNonUniform"; break;
|
||||||
|
case EOpAddInvocationsNonUniform: out.debug << "addInvocationsNonUniform"; break;
|
||||||
|
|
||||||
|
case EOpMinInvocationsInclusiveScan: out.debug << "minInvocationsInclusiveScan"; break;
|
||||||
|
case EOpMaxInvocationsInclusiveScan: out.debug << "maxInvocationsInclusiveScan"; break;
|
||||||
|
case EOpAddInvocationsInclusiveScan: out.debug << "addInvocationsInclusiveScan"; break;
|
||||||
|
case EOpMinInvocationsInclusiveScanNonUniform: out.debug << "minInvocationsInclusiveScanNonUniform"; break;
|
||||||
|
case EOpMaxInvocationsInclusiveScanNonUniform: out.debug << "maxInvocationsInclusiveScanNonUniform"; break;
|
||||||
|
case EOpAddInvocationsInclusiveScanNonUniform: out.debug << "addInvocationsInclusiveScanNonUniform"; break;
|
||||||
|
|
||||||
|
case EOpMinInvocationsExclusiveScan: out.debug << "minInvocationsExclusiveScan"; break;
|
||||||
|
case EOpMaxInvocationsExclusiveScan: out.debug << "maxInvocationsExclusiveScan"; break;
|
||||||
|
case EOpAddInvocationsExclusiveScan: out.debug << "addInvocationsExclusiveScan"; break;
|
||||||
|
case EOpMinInvocationsExclusiveScanNonUniform: out.debug << "minInvocationsExclusiveScanNonUniform"; break;
|
||||||
|
case EOpMaxInvocationsExclusiveScanNonUniform: out.debug << "maxInvocationsExclusiveScanNonUniform"; break;
|
||||||
|
case EOpAddInvocationsExclusiveScanNonUniform: out.debug << "addInvocationsExclusiveScanNonUniform"; break;
|
||||||
|
|
||||||
|
case EOpMbcnt: out.debug << "mbcnt"; break;
|
||||||
|
|
||||||
|
case EOpFragmentMaskFetch: out.debug << "fragmentMaskFetchAMD"; break;
|
||||||
|
case EOpFragmentFetch: out.debug << "fragmentFetchAMD"; break;
|
||||||
|
|
||||||
|
case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break;
|
||||||
|
case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad unary op");
|
default: out.debug.message(EPrefixError, "Bad unary op");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,29 +705,49 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
|
|
||||||
case EOpConstructFloat: out.debug << "Construct float"; break;
|
case EOpConstructFloat: out.debug << "Construct float"; break;
|
||||||
case EOpConstructDouble:out.debug << "Construct double"; break;
|
case EOpConstructDouble:out.debug << "Construct double"; break;
|
||||||
|
|
||||||
case EOpConstructVec2: out.debug << "Construct vec2"; break;
|
case EOpConstructVec2: out.debug << "Construct vec2"; break;
|
||||||
case EOpConstructVec3: out.debug << "Construct vec3"; break;
|
case EOpConstructVec3: out.debug << "Construct vec3"; break;
|
||||||
case EOpConstructVec4: out.debug << "Construct vec4"; break;
|
case EOpConstructVec4: out.debug << "Construct vec4"; break;
|
||||||
|
case EOpConstructDVec2: out.debug << "Construct dvec2"; break;
|
||||||
|
case EOpConstructDVec3: out.debug << "Construct dvec3"; break;
|
||||||
|
case EOpConstructDVec4: out.debug << "Construct dvec4"; break;
|
||||||
case EOpConstructBool: out.debug << "Construct bool"; break;
|
case EOpConstructBool: out.debug << "Construct bool"; break;
|
||||||
case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
|
case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
|
||||||
case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
|
case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
|
||||||
case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
|
case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
|
||||||
|
case EOpConstructInt8: out.debug << "Construct int8_t"; break;
|
||||||
|
case EOpConstructI8Vec2: out.debug << "Construct i8vec2"; break;
|
||||||
|
case EOpConstructI8Vec3: out.debug << "Construct i8vec3"; break;
|
||||||
|
case EOpConstructI8Vec4: out.debug << "Construct i8vec4"; break;
|
||||||
case EOpConstructInt: out.debug << "Construct int"; break;
|
case EOpConstructInt: out.debug << "Construct int"; break;
|
||||||
case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
|
case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
|
||||||
case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
|
case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
|
||||||
case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
|
case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
|
||||||
|
case EOpConstructUint8: out.debug << "Construct uint8_t"; break;
|
||||||
|
case EOpConstructU8Vec2: out.debug << "Construct u8vec2"; break;
|
||||||
|
case EOpConstructU8Vec3: out.debug << "Construct u8vec3"; break;
|
||||||
|
case EOpConstructU8Vec4: out.debug << "Construct u8vec4"; break;
|
||||||
case EOpConstructUint: out.debug << "Construct uint"; break;
|
case EOpConstructUint: out.debug << "Construct uint"; break;
|
||||||
case EOpConstructUVec2: out.debug << "Construct uvec2"; break;
|
case EOpConstructUVec2: out.debug << "Construct uvec2"; break;
|
||||||
case EOpConstructUVec3: out.debug << "Construct uvec3"; break;
|
case EOpConstructUVec3: out.debug << "Construct uvec3"; break;
|
||||||
case EOpConstructUVec4: out.debug << "Construct uvec4"; break;
|
case EOpConstructUVec4: out.debug << "Construct uvec4"; break;
|
||||||
case EOpConstructInt64: out.debug << "Construct int64_t"; break;
|
case EOpConstructInt64: out.debug << "Construct int64"; break;
|
||||||
case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break;
|
case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break;
|
||||||
case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break;
|
case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break;
|
||||||
case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break;
|
case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break;
|
||||||
case EOpConstructUint64: out.debug << "Construct uint64_t"; break;
|
case EOpConstructUint64: out.debug << "Construct uint64"; break;
|
||||||
case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
|
case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
|
||||||
case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
|
case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
|
||||||
case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
|
case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
|
||||||
|
case EOpConstructInt16: out.debug << "Construct int16_t"; break;
|
||||||
|
case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break;
|
||||||
|
case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break;
|
||||||
|
case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break;
|
||||||
|
case EOpConstructUint16: out.debug << "Construct uint16_t"; break;
|
||||||
|
case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break;
|
||||||
|
case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break;
|
||||||
|
case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break;
|
||||||
case EOpConstructMat2x2: out.debug << "Construct mat2"; break;
|
case EOpConstructMat2x2: out.debug << "Construct mat2"; break;
|
||||||
case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break;
|
case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break;
|
||||||
case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break;
|
case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break;
|
||||||
|
@ -437,6 +766,46 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
|
case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
|
||||||
case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
|
case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
|
||||||
case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break;
|
case EOpConstructDMat4x4: out.debug << "Construct dmat4"; break;
|
||||||
|
case EOpConstructIMat2x2: out.debug << "Construct imat2"; break;
|
||||||
|
case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break;
|
||||||
|
case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break;
|
||||||
|
case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break;
|
||||||
|
case EOpConstructIMat3x3: out.debug << "Construct imat3"; break;
|
||||||
|
case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break;
|
||||||
|
case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break;
|
||||||
|
case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break;
|
||||||
|
case EOpConstructIMat4x4: out.debug << "Construct imat4"; break;
|
||||||
|
case EOpConstructUMat2x2: out.debug << "Construct umat2"; break;
|
||||||
|
case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break;
|
||||||
|
case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break;
|
||||||
|
case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break;
|
||||||
|
case EOpConstructUMat3x3: out.debug << "Construct umat3"; break;
|
||||||
|
case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break;
|
||||||
|
case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break;
|
||||||
|
case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break;
|
||||||
|
case EOpConstructUMat4x4: out.debug << "Construct umat4"; break;
|
||||||
|
case EOpConstructBMat2x2: out.debug << "Construct bmat2"; break;
|
||||||
|
case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break;
|
||||||
|
case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break;
|
||||||
|
case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break;
|
||||||
|
case EOpConstructBMat3x3: out.debug << "Construct bmat3"; break;
|
||||||
|
case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break;
|
||||||
|
case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
|
||||||
|
case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
|
||||||
|
case EOpConstructBMat4x4: out.debug << "Construct bmat4"; break;
|
||||||
|
case EOpConstructFloat16: out.debug << "Construct float16_t"; break;
|
||||||
|
case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break;
|
||||||
|
case EOpConstructF16Vec3: out.debug << "Construct f16vec3"; break;
|
||||||
|
case EOpConstructF16Vec4: out.debug << "Construct f16vec4"; break;
|
||||||
|
case EOpConstructF16Mat2x2: out.debug << "Construct f16mat2"; break;
|
||||||
|
case EOpConstructF16Mat2x3: out.debug << "Construct f16mat2x3"; break;
|
||||||
|
case EOpConstructF16Mat2x4: out.debug << "Construct f16mat2x4"; break;
|
||||||
|
case EOpConstructF16Mat3x2: out.debug << "Construct f16mat3x2"; break;
|
||||||
|
case EOpConstructF16Mat3x3: out.debug << "Construct f16mat3"; break;
|
||||||
|
case EOpConstructF16Mat3x4: out.debug << "Construct f16mat3x4"; break;
|
||||||
|
case EOpConstructF16Mat4x2: out.debug << "Construct f16mat4x2"; break;
|
||||||
|
case EOpConstructF16Mat4x3: out.debug << "Construct f16mat4x3"; break;
|
||||||
|
case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4"; break;
|
||||||
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
case EOpConstructStruct: out.debug << "Construct structure"; break;
|
||||||
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
|
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
|
||||||
|
|
||||||
|
@ -482,6 +851,18 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
|
|
||||||
case EOpReadInvocation: out.debug << "readInvocation"; break;
|
case EOpReadInvocation: out.debug << "readInvocation"; break;
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break;
|
||||||
|
case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break;
|
||||||
|
case EOpWriteInvocation: out.debug << "writeInvocation"; break;
|
||||||
|
|
||||||
|
case EOpMin3: out.debug << "min3"; break;
|
||||||
|
case EOpMax3: out.debug << "max3"; break;
|
||||||
|
case EOpMid3: out.debug << "mid3"; break;
|
||||||
|
|
||||||
|
case EOpTime: out.debug << "time"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpAtomicAdd: out.debug << "AtomicAdd"; break;
|
case EOpAtomicAdd: out.debug << "AtomicAdd"; break;
|
||||||
case EOpAtomicMin: out.debug << "AtomicMin"; break;
|
case EOpAtomicMin: out.debug << "AtomicMin"; break;
|
||||||
case EOpAtomicMax: out.debug << "AtomicMax"; break;
|
case EOpAtomicMax: out.debug << "AtomicMax"; break;
|
||||||
|
@ -491,6 +872,16 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpAtomicExchange: out.debug << "AtomicExchange"; break;
|
case EOpAtomicExchange: out.debug << "AtomicExchange"; break;
|
||||||
case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break;
|
case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break;
|
||||||
|
|
||||||
|
case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break;
|
||||||
|
case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break;
|
||||||
|
case EOpAtomicCounterMin: out.debug << "AtomicCounterMin"; break;
|
||||||
|
case EOpAtomicCounterMax: out.debug << "AtomicCounterMax"; break;
|
||||||
|
case EOpAtomicCounterAnd: out.debug << "AtomicCounterAnd"; break;
|
||||||
|
case EOpAtomicCounterOr: out.debug << "AtomicCounterOr"; break;
|
||||||
|
case EOpAtomicCounterXor: out.debug << "AtomicCounterXor"; break;
|
||||||
|
case EOpAtomicCounterExchange: out.debug << "AtomicCounterExchange"; break;
|
||||||
|
case EOpAtomicCounterCompSwap: out.debug << "AtomicCounterCompSwap"; break;
|
||||||
|
|
||||||
case EOpImageQuerySize: out.debug << "imageQuerySize"; break;
|
case EOpImageQuerySize: out.debug << "imageQuerySize"; break;
|
||||||
case EOpImageQuerySamples: out.debug << "imageQuerySamples"; break;
|
case EOpImageQuerySamples: out.debug << "imageQuerySamples"; break;
|
||||||
case EOpImageLoad: out.debug << "imageLoad"; break;
|
case EOpImageLoad: out.debug << "imageLoad"; break;
|
||||||
|
@ -503,6 +894,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break;
|
case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break;
|
||||||
case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break;
|
case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break;
|
||||||
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
||||||
|
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpTextureQuerySize: out.debug << "textureSize"; break;
|
case EOpTextureQuerySize: out.debug << "textureSize"; break;
|
||||||
case EOpTextureQueryLod: out.debug << "textureQueryLod"; break;
|
case EOpTextureQueryLod: out.debug << "textureQueryLod"; break;
|
||||||
|
@ -525,6 +920,38 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
case EOpTextureGather: out.debug << "textureGather"; break;
|
case EOpTextureGather: out.debug << "textureGather"; break;
|
||||||
case EOpTextureGatherOffset: out.debug << "textureGatherOffset"; break;
|
case EOpTextureGatherOffset: out.debug << "textureGatherOffset"; break;
|
||||||
case EOpTextureGatherOffsets: out.debug << "textureGatherOffsets"; break;
|
case EOpTextureGatherOffsets: out.debug << "textureGatherOffsets"; break;
|
||||||
|
case EOpTextureClamp: out.debug << "textureClamp"; break;
|
||||||
|
case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break;
|
||||||
|
case EOpTextureGradClamp: out.debug << "textureGradClamp"; break;
|
||||||
|
case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpTextureGatherLod: out.debug << "textureGatherLod"; break;
|
||||||
|
case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break;
|
||||||
|
case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case EOpSparseTexture: out.debug << "sparseTexture"; break;
|
||||||
|
case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break;
|
||||||
|
case EOpSparseTextureLod: out.debug << "sparseTextureLod"; break;
|
||||||
|
case EOpSparseTextureLodOffset: out.debug << "sparseTextureLodOffset"; break;
|
||||||
|
case EOpSparseTextureFetch: out.debug << "sparseTexelFetch"; break;
|
||||||
|
case EOpSparseTextureFetchOffset: out.debug << "sparseTexelFetchOffset"; break;
|
||||||
|
case EOpSparseTextureGrad: out.debug << "sparseTextureGrad"; break;
|
||||||
|
case EOpSparseTextureGradOffset: out.debug << "sparseTextureGradOffset"; break;
|
||||||
|
case EOpSparseTextureGather: out.debug << "sparseTextureGather"; break;
|
||||||
|
case EOpSparseTextureGatherOffset: out.debug << "sparseTextureGatherOffset"; break;
|
||||||
|
case EOpSparseTextureGatherOffsets: out.debug << "sparseTextureGatherOffsets"; break;
|
||||||
|
case EOpSparseImageLoad: out.debug << "sparseImageLoad"; break;
|
||||||
|
case EOpSparseTextureClamp: out.debug << "sparseTextureClamp"; break;
|
||||||
|
case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break;
|
||||||
|
case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break;
|
||||||
|
case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break;
|
||||||
|
case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break;
|
||||||
|
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
||||||
|
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpAddCarry: out.debug << "addCarry"; break;
|
case EOpAddCarry: out.debug << "addCarry"; break;
|
||||||
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
||||||
|
@ -539,15 +966,78 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
||||||
|
|
||||||
case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break;
|
case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break;
|
||||||
case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break;
|
case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case EOpSinCos: out.debug << "sincos"; break;
|
case EOpSinCos: out.debug << "sincos"; break;
|
||||||
case EOpGenMul: out.debug << "mul"; break;
|
case EOpGenMul: out.debug << "mul"; break;
|
||||||
|
|
||||||
case EOpAllMemoryBarrierWithGroupSync: out.debug << "AllMemoryBarrierWithGroupSync"; break;
|
case EOpAllMemoryBarrierWithGroupSync: out.debug << "AllMemoryBarrierWithGroupSync"; break;
|
||||||
case EOpGroupMemoryBarrierWithGroupSync: out.debug << "GroupMemoryBarrierWithGroupSync"; break;
|
case EOpDeviceMemoryBarrier: out.debug << "DeviceMemoryBarrier"; break;
|
||||||
|
case EOpDeviceMemoryBarrierWithGroupSync: out.debug << "DeviceMemoryBarrierWithGroupSync"; break;
|
||||||
case EOpWorkgroupMemoryBarrier: out.debug << "WorkgroupMemoryBarrier"; break;
|
case EOpWorkgroupMemoryBarrier: out.debug << "WorkgroupMemoryBarrier"; break;
|
||||||
case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break;
|
case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break;
|
||||||
|
|
||||||
|
case EOpSubgroupBarrier: out.debug << "subgroupBarrier"; break;
|
||||||
|
case EOpSubgroupMemoryBarrier: out.debug << "subgroupMemoryBarrier"; break;
|
||||||
|
case EOpSubgroupMemoryBarrierBuffer: out.debug << "subgroupMemoryBarrierBuffer"; break;
|
||||||
|
case EOpSubgroupMemoryBarrierImage: out.debug << "subgroupMemoryBarrierImage"; break;
|
||||||
|
case EOpSubgroupMemoryBarrierShared: out.debug << "subgroupMemoryBarrierShared"; break;
|
||||||
|
case EOpSubgroupElect: out.debug << "subgroupElect"; break;
|
||||||
|
case EOpSubgroupAll: out.debug << "subgroupAll"; break;
|
||||||
|
case EOpSubgroupAny: out.debug << "subgroupAny"; break;
|
||||||
|
case EOpSubgroupAllEqual: out.debug << "subgroupAllEqual"; break;
|
||||||
|
case EOpSubgroupBroadcast: out.debug << "subgroupBroadcast"; break;
|
||||||
|
case EOpSubgroupBroadcastFirst: out.debug << "subgroupBroadcastFirst"; break;
|
||||||
|
case EOpSubgroupBallot: out.debug << "subgroupBallot"; break;
|
||||||
|
case EOpSubgroupInverseBallot: out.debug << "subgroupInverseBallot"; break;
|
||||||
|
case EOpSubgroupBallotBitExtract: out.debug << "subgroupBallotBitExtract"; break;
|
||||||
|
case EOpSubgroupBallotBitCount: out.debug << "subgroupBallotBitCount"; break;
|
||||||
|
case EOpSubgroupBallotInclusiveBitCount: out.debug << "subgroupBallotInclusiveBitCount"; break;
|
||||||
|
case EOpSubgroupBallotExclusiveBitCount: out.debug << "subgroupBallotExclusiveBitCount"; break;
|
||||||
|
case EOpSubgroupBallotFindLSB: out.debug << "subgroupBallotFindLSB"; break;
|
||||||
|
case EOpSubgroupBallotFindMSB: out.debug << "subgroupBallotFindMSB"; break;
|
||||||
|
case EOpSubgroupShuffle: out.debug << "subgroupShuffle"; break;
|
||||||
|
case EOpSubgroupShuffleXor: out.debug << "subgroupShuffleXor"; break;
|
||||||
|
case EOpSubgroupShuffleUp: out.debug << "subgroupShuffleUp"; break;
|
||||||
|
case EOpSubgroupShuffleDown: out.debug << "subgroupShuffleDown"; break;
|
||||||
|
case EOpSubgroupAdd: out.debug << "subgroupAdd"; break;
|
||||||
|
case EOpSubgroupMul: out.debug << "subgroupMul"; break;
|
||||||
|
case EOpSubgroupMin: out.debug << "subgroupMin"; break;
|
||||||
|
case EOpSubgroupMax: out.debug << "subgroupMax"; break;
|
||||||
|
case EOpSubgroupAnd: out.debug << "subgroupAnd"; break;
|
||||||
|
case EOpSubgroupOr: out.debug << "subgroupOr"; break;
|
||||||
|
case EOpSubgroupXor: out.debug << "subgroupXor"; break;
|
||||||
|
case EOpSubgroupInclusiveAdd: out.debug << "subgroupInclusiveAdd"; break;
|
||||||
|
case EOpSubgroupInclusiveMul: out.debug << "subgroupInclusiveMul"; break;
|
||||||
|
case EOpSubgroupInclusiveMin: out.debug << "subgroupInclusiveMin"; break;
|
||||||
|
case EOpSubgroupInclusiveMax: out.debug << "subgroupInclusiveMax"; break;
|
||||||
|
case EOpSubgroupInclusiveAnd: out.debug << "subgroupInclusiveAnd"; break;
|
||||||
|
case EOpSubgroupInclusiveOr: out.debug << "subgroupInclusiveOr"; break;
|
||||||
|
case EOpSubgroupInclusiveXor: out.debug << "subgroupInclusiveXor"; break;
|
||||||
|
case EOpSubgroupExclusiveAdd: out.debug << "subgroupExclusiveAdd"; break;
|
||||||
|
case EOpSubgroupExclusiveMul: out.debug << "subgroupExclusiveMul"; break;
|
||||||
|
case EOpSubgroupExclusiveMin: out.debug << "subgroupExclusiveMin"; break;
|
||||||
|
case EOpSubgroupExclusiveMax: out.debug << "subgroupExclusiveMax"; break;
|
||||||
|
case EOpSubgroupExclusiveAnd: out.debug << "subgroupExclusiveAnd"; break;
|
||||||
|
case EOpSubgroupExclusiveOr: out.debug << "subgroupExclusiveOr"; break;
|
||||||
|
case EOpSubgroupExclusiveXor: out.debug << "subgroupExclusiveXor"; break;
|
||||||
|
case EOpSubgroupClusteredAdd: out.debug << "subgroupClusteredAdd"; break;
|
||||||
|
case EOpSubgroupClusteredMul: out.debug << "subgroupClusteredMul"; break;
|
||||||
|
case EOpSubgroupClusteredMin: out.debug << "subgroupClusteredMin"; break;
|
||||||
|
case EOpSubgroupClusteredMax: out.debug << "subgroupClusteredMax"; break;
|
||||||
|
case EOpSubgroupClusteredAnd: out.debug << "subgroupClusteredAnd"; break;
|
||||||
|
case EOpSubgroupClusteredOr: out.debug << "subgroupClusteredOr"; break;
|
||||||
|
case EOpSubgroupClusteredXor: out.debug << "subgroupClusteredXor"; break;
|
||||||
|
case EOpSubgroupQuadBroadcast: out.debug << "subgroupQuadBroadcast"; break;
|
||||||
|
case EOpSubgroupQuadSwapHorizontal: out.debug << "subgroupQuadSwapHorizontal"; break;
|
||||||
|
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
|
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
||||||
|
|
||||||
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +1056,15 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
|
||||||
OutputTreeText(out, node, depth);
|
OutputTreeText(out, node, depth);
|
||||||
|
|
||||||
out.debug << "Test condition and select";
|
out.debug << "Test condition and select";
|
||||||
out.debug << " (" << node->getCompleteString() << ")\n";
|
out.debug << " (" << node->getCompleteString() << ")";
|
||||||
|
|
||||||
|
if (node->getShortCircuit() == false)
|
||||||
|
out.debug << ": no shortcircuit";
|
||||||
|
if (node->getFlatten())
|
||||||
|
out.debug << ": Flatten";
|
||||||
|
if (node->getDontFlatten())
|
||||||
|
out.debug << ": DontFlatten";
|
||||||
|
out.debug << "\n";
|
||||||
|
|
||||||
++depth;
|
++depth;
|
||||||
|
|
||||||
|
@ -592,7 +1090,61 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth)
|
// Print infinities and NaNs, and numbers in a portable way.
|
||||||
|
// Goals:
|
||||||
|
// - portable (across IEEE 754 platforms)
|
||||||
|
// - shows all possible IEEE values
|
||||||
|
// - shows simple numbers in a simple way, e.g., no leading/trailing 0s
|
||||||
|
// - shows all digits, no premature rounding
|
||||||
|
static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra)
|
||||||
|
{
|
||||||
|
if (IsInfinity(value)) {
|
||||||
|
if (value < 0)
|
||||||
|
out.debug << "-1.#INF";
|
||||||
|
else
|
||||||
|
out.debug << "+1.#INF";
|
||||||
|
} else if (IsNan(value))
|
||||||
|
out.debug << "1.#IND";
|
||||||
|
else {
|
||||||
|
const int maxSize = 340;
|
||||||
|
char buf[maxSize];
|
||||||
|
const char* format = "%f";
|
||||||
|
if (fabs(value) > 0.0 && (fabs(value) < 1e-5 || fabs(value) > 1e12))
|
||||||
|
format = "%-.13e";
|
||||||
|
int len = snprintf(buf, maxSize, format, value);
|
||||||
|
assert(len < maxSize);
|
||||||
|
|
||||||
|
// remove a leading zero in the 100s slot in exponent; it is not portable
|
||||||
|
// pattern: XX...XXXe+0XX or XX...XXXe-0XX
|
||||||
|
if (len > 5) {
|
||||||
|
if (buf[len-5] == 'e' && (buf[len-4] == '+' || buf[len-4] == '-') && buf[len-3] == '0') {
|
||||||
|
buf[len-3] = buf[len-2];
|
||||||
|
buf[len-2] = buf[len-1];
|
||||||
|
buf[len-1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.debug << buf;
|
||||||
|
|
||||||
|
switch (extra) {
|
||||||
|
case TOutputTraverser::BinaryDoubleOutput:
|
||||||
|
{
|
||||||
|
out.debug << " : ";
|
||||||
|
long long b = *reinterpret_cast<long long*>(&value);
|
||||||
|
for (int i = 0; i < 8 * sizeof(value); ++i, ++b) {
|
||||||
|
out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0");
|
||||||
|
b <<= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion,
|
||||||
|
TOutputTraverser::EExtraOutput extra, int depth)
|
||||||
{
|
{
|
||||||
int size = node->getType().computeNumComponents();
|
int size = node->getType().computeNumComponents();
|
||||||
|
|
||||||
|
@ -611,20 +1163,44 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
|
||||||
break;
|
break;
|
||||||
case EbtFloat:
|
case EbtFloat:
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
|
case EbtFloat16:
|
||||||
|
OutputDouble(out, constUnion[i].getDConst(), extra);
|
||||||
|
out.debug << "\n";
|
||||||
|
break;
|
||||||
|
case EbtInt8:
|
||||||
{
|
{
|
||||||
const double value = constUnion[i].getDConst();
|
|
||||||
// Print infinity in a portable way, for test stability.
|
|
||||||
// Other cases may be needed in the future: negative infinity,
|
|
||||||
// and NaNs.
|
|
||||||
if (is_positive_infinity(value))
|
|
||||||
out.debug << "inf\n";
|
|
||||||
else {
|
|
||||||
const int maxSize = 300;
|
const int maxSize = 300;
|
||||||
char buf[maxSize];
|
char buf[maxSize];
|
||||||
snprintf(buf, maxSize, "%f", value);
|
snprintf(buf, maxSize, "%d (%s)", constUnion[i].getI8Const(), "const int8_t");
|
||||||
|
|
||||||
out.debug << buf << "\n";
|
out.debug << buf << "\n";
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint8:
|
||||||
|
{
|
||||||
|
const int maxSize = 300;
|
||||||
|
char buf[maxSize];
|
||||||
|
snprintf(buf, maxSize, "%u (%s)", constUnion[i].getU8Const(), "const uint8_t");
|
||||||
|
|
||||||
|
out.debug << buf << "\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtInt16:
|
||||||
|
{
|
||||||
|
const int maxSize = 300;
|
||||||
|
char buf[maxSize];
|
||||||
|
snprintf(buf, maxSize, "%d (%s)", constUnion[i].getI16Const(), "const int16_t");
|
||||||
|
|
||||||
|
out.debug << buf << "\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint16:
|
||||||
|
{
|
||||||
|
const int maxSize = 300;
|
||||||
|
char buf[maxSize];
|
||||||
|
snprintf(buf, maxSize, "%u (%s)", constUnion[i].getU16Const(), "const uint16_t");
|
||||||
|
|
||||||
|
out.debug << buf << "\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
|
@ -675,7 +1251,7 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||||
OutputTreeText(infoSink, node, depth);
|
OutputTreeText(infoSink, node, depth);
|
||||||
infoSink.debug << "Constant:\n";
|
infoSink.debug << "Constant:\n";
|
||||||
|
|
||||||
OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1);
|
OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TOutputTraverser::visitSymbol(TIntermSymbol* node)
|
void TOutputTraverser::visitSymbol(TIntermSymbol* node)
|
||||||
|
@ -685,7 +1261,7 @@ void TOutputTraverser::visitSymbol(TIntermSymbol* node)
|
||||||
infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n";
|
infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n";
|
||||||
|
|
||||||
if (! node->getConstArray().empty())
|
if (! node->getConstArray().empty())
|
||||||
OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1);
|
OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1);
|
||||||
else if (node->getConstSubtree()) {
|
else if (node->getConstSubtree()) {
|
||||||
incrementDepth(node);
|
incrementDepth(node);
|
||||||
node->getConstSubtree()->traverse(this);
|
node->getConstSubtree()->traverse(this);
|
||||||
|
@ -702,7 +1278,17 @@ bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node)
|
||||||
out.debug << "Loop with condition ";
|
out.debug << "Loop with condition ";
|
||||||
if (! node->testFirst())
|
if (! node->testFirst())
|
||||||
out.debug << "not ";
|
out.debug << "not ";
|
||||||
out.debug << "tested first\n";
|
out.debug << "tested first";
|
||||||
|
|
||||||
|
if (node->getUnroll())
|
||||||
|
out.debug << ": Unroll";
|
||||||
|
if (node->getDontUnroll())
|
||||||
|
out.debug << ": DontUnroll";
|
||||||
|
if (node->getLoopDependency()) {
|
||||||
|
out.debug << ": Dependency ";
|
||||||
|
out.debug << node->getLoopDependency();
|
||||||
|
}
|
||||||
|
out.debug << "\n";
|
||||||
|
|
||||||
++depth;
|
++depth;
|
||||||
|
|
||||||
|
@ -763,7 +1349,13 @@ bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node)
|
||||||
TInfoSink& out = infoSink;
|
TInfoSink& out = infoSink;
|
||||||
|
|
||||||
OutputTreeText(out, node, depth);
|
OutputTreeText(out, node, depth);
|
||||||
out.debug << "switch\n";
|
out.debug << "switch";
|
||||||
|
|
||||||
|
if (node->getFlatten())
|
||||||
|
out.debug << ": Flatten";
|
||||||
|
if (node->getDontFlatten())
|
||||||
|
out.debug << ": DontFlatten";
|
||||||
|
out.debug << "\n";
|
||||||
|
|
||||||
OutputTreeText(out, node, depth);
|
OutputTreeText(out, node, depth);
|
||||||
out.debug << "condition\n";
|
out.debug << "condition\n";
|
||||||
|
@ -803,6 +1395,13 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
||||||
|
|
||||||
case EShLangTessControl:
|
case EShLangTessControl:
|
||||||
infoSink.debug << "vertices = " << vertices << "\n";
|
infoSink.debug << "vertices = " << vertices << "\n";
|
||||||
|
|
||||||
|
if (inputPrimitive != ElgNone)
|
||||||
|
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
|
||||||
|
if (vertexSpacing != EvsNone)
|
||||||
|
infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
|
||||||
|
if (vertexOrder != EvoNone)
|
||||||
|
infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EShLangTessEvaluation:
|
case EShLangTessEvaluation:
|
||||||
|
@ -827,6 +1426,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
||||||
infoSink.debug << "gl_FragCoord origin is upper left\n";
|
infoSink.debug << "gl_FragCoord origin is upper left\n";
|
||||||
if (earlyFragmentTests)
|
if (earlyFragmentTests)
|
||||||
infoSink.debug << "using early_fragment_tests\n";
|
infoSink.debug << "using early_fragment_tests\n";
|
||||||
|
if (postDepthCoverage)
|
||||||
|
infoSink.debug << "using post_depth_coverage\n";
|
||||||
if (depthLayout != EldNone)
|
if (depthLayout != EldNone)
|
||||||
infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
|
infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
|
||||||
if (blendEquations != 0) {
|
if (blendEquations != 0) {
|
||||||
|
@ -862,7 +1463,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TOutputTraverser it(infoSink);
|
TOutputTraverser it(infoSink);
|
||||||
|
if (getBinaryDoubleOutput())
|
||||||
|
it.setDoubleOutput(TOutputTraverser::BinaryDoubleOutput);
|
||||||
treeRoot->traverse(&it);
|
treeRoot->traverse(&it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,798 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016-2017 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../Include/Common.h"
|
||||||
|
#include "../Include/InfoSink.h"
|
||||||
|
#include "iomapper.h"
|
||||||
|
#include "LiveTraverser.h"
|
||||||
|
#include "localintermediate.h"
|
||||||
|
|
||||||
|
#include "gl_types.h"
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Map IO bindings.
|
||||||
|
//
|
||||||
|
// High-level algorithm for one stage:
|
||||||
|
//
|
||||||
|
// 1. Traverse all code (live+dead) to find the explicitly provided bindings.
|
||||||
|
//
|
||||||
|
// 2. Traverse (just) the live code to determine which non-provided bindings
|
||||||
|
// require auto-numbering. We do not auto-number dead ones.
|
||||||
|
//
|
||||||
|
// 3. Traverse all the code to apply the bindings:
|
||||||
|
// a. explicitly given bindings are offset according to their type
|
||||||
|
// b. implicit live bindings are auto-numbered into the holes, using
|
||||||
|
// any open binding slot.
|
||||||
|
// c. implicit dead bindings are left un-bound.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
struct TVarEntryInfo
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
TIntermSymbol* symbol;
|
||||||
|
bool live;
|
||||||
|
int newBinding;
|
||||||
|
int newSet;
|
||||||
|
int newLocation;
|
||||||
|
int newComponent;
|
||||||
|
int newIndex;
|
||||||
|
|
||||||
|
struct TOrderById
|
||||||
|
{
|
||||||
|
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r)
|
||||||
|
{
|
||||||
|
return l.id < r.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TOrderByPriority
|
||||||
|
{
|
||||||
|
// ordering:
|
||||||
|
// 1) has both binding and set
|
||||||
|
// 2) has binding but no set
|
||||||
|
// 3) has no binding but set
|
||||||
|
// 4) has no binding and no set
|
||||||
|
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r)
|
||||||
|
{
|
||||||
|
const TQualifier& lq = l.symbol->getQualifier();
|
||||||
|
const TQualifier& rq = r.symbol->getQualifier();
|
||||||
|
|
||||||
|
// simple rules:
|
||||||
|
// has binding gives 2 points
|
||||||
|
// has set gives 1 point
|
||||||
|
// who has the most points is more important.
|
||||||
|
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
|
||||||
|
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
|
||||||
|
|
||||||
|
if (lPoints == rPoints)
|
||||||
|
return l.id < r.id;
|
||||||
|
return lPoints > rPoints;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::vector<TVarEntryInfo> TVarLiveMap;
|
||||||
|
|
||||||
|
class TVarGatherTraverser : public TLiveTraverser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList)
|
||||||
|
: TLiveTraverser(i, traverseDeadCode, true, true, false)
|
||||||
|
, inputList(inList)
|
||||||
|
, outputList(outList)
|
||||||
|
, uniformList(uniformList)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void visitSymbol(TIntermSymbol* base)
|
||||||
|
{
|
||||||
|
TVarLiveMap* target = nullptr;
|
||||||
|
if (base->getQualifier().storage == EvqVaryingIn)
|
||||||
|
target = &inputList;
|
||||||
|
else if (base->getQualifier().storage == EvqVaryingOut)
|
||||||
|
target = &outputList;
|
||||||
|
else if (base->getQualifier().isUniformOrBuffer() && !base->getQualifier().layoutPushConstant)
|
||||||
|
target = &uniformList;
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
TVarEntryInfo ent = { base->getId(), base, !traverseAll };
|
||||||
|
TVarLiveMap::iterator at = std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById());
|
||||||
|
if (at != target->end() && at->id == ent.id)
|
||||||
|
at->live = at->live || !traverseAll; // update live state
|
||||||
|
else
|
||||||
|
target->insert(at, ent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TVarLiveMap& inputList;
|
||||||
|
TVarLiveMap& outputList;
|
||||||
|
TVarLiveMap& uniformList;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TVarSetTraverser : public TLiveTraverser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& inList, const TVarLiveMap& outList, const TVarLiveMap& uniformList)
|
||||||
|
: TLiveTraverser(i, true, true, true, false)
|
||||||
|
, inputList(inList)
|
||||||
|
, outputList(outList)
|
||||||
|
, uniformList(uniformList)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void visitSymbol(TIntermSymbol* base)
|
||||||
|
{
|
||||||
|
const TVarLiveMap* source;
|
||||||
|
if (base->getQualifier().storage == EvqVaryingIn)
|
||||||
|
source = &inputList;
|
||||||
|
else if (base->getQualifier().storage == EvqVaryingOut)
|
||||||
|
source = &outputList;
|
||||||
|
else if (base->getQualifier().isUniformOrBuffer())
|
||||||
|
source = &uniformList;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
TVarEntryInfo ent = { base->getId() };
|
||||||
|
TVarLiveMap::const_iterator at = std::lower_bound(source->begin(), source->end(), ent, TVarEntryInfo::TOrderById());
|
||||||
|
if (at == source->end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (at->id != ent.id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (at->newBinding != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutBinding = at->newBinding;
|
||||||
|
if (at->newSet != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutSet = at->newSet;
|
||||||
|
if (at->newLocation != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutLocation = at->newLocation;
|
||||||
|
if (at->newComponent != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutComponent = at->newComponent;
|
||||||
|
if (at->newIndex != -1)
|
||||||
|
base->getWritableType().getQualifier().layoutIndex = at->newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const TVarLiveMap& inputList;
|
||||||
|
const TVarLiveMap& outputList;
|
||||||
|
const TVarLiveMap& uniformList;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TNotifyUniformAdaptor
|
||||||
|
{
|
||||||
|
EShLanguage stage;
|
||||||
|
TIoMapResolver& resolver;
|
||||||
|
inline TNotifyUniformAdaptor(EShLanguage s, TIoMapResolver& r)
|
||||||
|
: stage(s)
|
||||||
|
, resolver(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
|
{
|
||||||
|
resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TNotifyInOutAdaptor
|
||||||
|
{
|
||||||
|
EShLanguage stage;
|
||||||
|
TIoMapResolver& resolver;
|
||||||
|
inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
|
||||||
|
: stage(s)
|
||||||
|
, resolver(r)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
|
{
|
||||||
|
resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TResolverUniformAdaptor
|
||||||
|
{
|
||||||
|
TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
|
||||||
|
: stage(s)
|
||||||
|
, resolver(r)
|
||||||
|
, infoSink(i)
|
||||||
|
, error(e)
|
||||||
|
, intermediate(interm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
|
{
|
||||||
|
ent.newLocation = -1;
|
||||||
|
ent.newComponent = -1;
|
||||||
|
ent.newBinding = -1;
|
||||||
|
ent.newSet = -1;
|
||||||
|
ent.newIndex = -1;
|
||||||
|
const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
if (isValid) {
|
||||||
|
ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
ent.newSet = resolver.resolveSet(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||||
|
ent.newLocation = resolver.resolveUniformLocation(stage, ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(), ent.live);
|
||||||
|
|
||||||
|
if (ent.newBinding != -1) {
|
||||||
|
if (ent.newBinding >= int(TQualifier::layoutBindingEnd)) {
|
||||||
|
TString err = "mapped binding out of range: " + ent.symbol->getName();
|
||||||
|
|
||||||
|
infoSink.info.message(EPrefixInternalError, err.c_str());
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ent.newSet != -1) {
|
||||||
|
if (ent.newSet >= int(TQualifier::layoutSetEnd)) {
|
||||||
|
TString err = "mapped set out of range: " + ent.symbol->getName();
|
||||||
|
|
||||||
|
infoSink.info.message(EPrefixInternalError, err.c_str());
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TString errorMsg = "Invalid binding: " + ent.symbol->getName();
|
||||||
|
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EShLanguage stage;
|
||||||
|
TIoMapResolver& resolver;
|
||||||
|
TInfoSink& infoSink;
|
||||||
|
bool& error;
|
||||||
|
TIntermediate& intermediate;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TResolverInOutAdaptor
|
||||||
|
{
|
||||||
|
TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
|
||||||
|
: stage(s)
|
||||||
|
, resolver(r)
|
||||||
|
, infoSink(i)
|
||||||
|
, error(e)
|
||||||
|
, intermediate(interm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void operator()(TVarEntryInfo& ent)
|
||||||
|
{
|
||||||
|
ent.newLocation = -1;
|
||||||
|
ent.newComponent = -1;
|
||||||
|
ent.newBinding = -1;
|
||||||
|
ent.newSet = -1;
|
||||||
|
ent.newIndex = -1;
|
||||||
|
const bool isValid = resolver.validateInOut(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
if (isValid) {
|
||||||
|
ent.newLocation = resolver.resolveInOutLocation(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
ent.newComponent = resolver.resolveInOutComponent(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
ent.newIndex = resolver.resolveInOutIndex(stage,
|
||||||
|
ent.symbol->getName().c_str(),
|
||||||
|
ent.symbol->getType(),
|
||||||
|
ent.live);
|
||||||
|
} else {
|
||||||
|
TString errorMsg = "Invalid shader In/Out variable semantic: ";
|
||||||
|
errorMsg += ent.symbol->getType().getQualifier().semanticName;
|
||||||
|
infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EShLanguage stage;
|
||||||
|
TIoMapResolver& resolver;
|
||||||
|
TInfoSink& infoSink;
|
||||||
|
bool& error;
|
||||||
|
TIntermediate& intermediate;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Base class for shared TIoMapResolver services, used by several derivations.
|
||||||
|
struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
||||||
|
{
|
||||||
|
TDefaultIoResolverBase(const TIntermediate &intermediate) :
|
||||||
|
intermediate(intermediate),
|
||||||
|
nextUniformLocation(0),
|
||||||
|
nextInputLocation(0),
|
||||||
|
nextOutputLocation(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
int getBaseBinding(TResourceType res, unsigned int set) const {
|
||||||
|
return selectBaseBinding(intermediate.getShiftBinding(res),
|
||||||
|
intermediate.getShiftBindingForSet(res, set));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); }
|
||||||
|
|
||||||
|
bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
|
||||||
|
bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
|
||||||
|
|
||||||
|
typedef std::vector<int> TSlotSet;
|
||||||
|
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
||||||
|
TSlotSetMap slots;
|
||||||
|
|
||||||
|
TSlotSet::iterator findSlot(int set, int slot)
|
||||||
|
{
|
||||||
|
return std::lower_bound(slots[set].begin(), slots[set].end(), slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkEmpty(int set, int slot)
|
||||||
|
{
|
||||||
|
TSlotSet::iterator at = findSlot(set, slot);
|
||||||
|
return !(at != slots[set].end() && *at == slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
int reserveSlot(int set, int slot)
|
||||||
|
{
|
||||||
|
TSlotSet::iterator at = findSlot(set, slot);
|
||||||
|
|
||||||
|
// tolerate aliasing, by not double-recording aliases
|
||||||
|
// (policy about appropriateness of the alias is higher up)
|
||||||
|
if (at == slots[set].end() || *at != slot)
|
||||||
|
slots[set].insert(at, slot);
|
||||||
|
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFreeSlot(int set, int base)
|
||||||
|
{
|
||||||
|
TSlotSet::iterator at = findSlot(set, base);
|
||||||
|
if (at == slots[set].end())
|
||||||
|
return reserveSlot(set, base);
|
||||||
|
|
||||||
|
// look in locksteps, if they not match, then there is a free slot
|
||||||
|
for (; at != slots[set].end(); ++at, ++base)
|
||||||
|
if (*at != base)
|
||||||
|
break;
|
||||||
|
return reserveSlot(set, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0;
|
||||||
|
|
||||||
|
virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0;
|
||||||
|
|
||||||
|
int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
if (type.getQualifier().hasSet())
|
||||||
|
return type.getQualifier().layoutSet;
|
||||||
|
|
||||||
|
// If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
|
||||||
|
if (getResourceSetBinding().size() == 1)
|
||||||
|
return atoi(getResourceSetBinding()[0].c_str());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
// kick out of not doing this
|
||||||
|
if (!doAutoLocationMapping())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||||
|
if (type.getQualifier().hasLocation() || type.isBuiltIn() ||
|
||||||
|
type.getBasicType() == EbtBlock ||
|
||||||
|
type.getBasicType() == EbtAtomicUint ||
|
||||||
|
(type.containsOpaque() && intermediate.getSpv().openGl == 0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// no locations on blocks of built-in variables
|
||||||
|
if (type.isStruct()) {
|
||||||
|
if (type.getStruct()->size() < 1)
|
||||||
|
return -1;
|
||||||
|
if ((*type.getStruct())[0].type->isBuiltIn())
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int location = nextUniformLocation;
|
||||||
|
|
||||||
|
nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type);
|
||||||
|
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int resolveInOutLocation(EShLanguage stage, const char* /*name*/, const TType& type, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
// kick out of not doing this
|
||||||
|
if (!doAutoLocationMapping())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// no locations added if already present, or a built-in variable
|
||||||
|
if (type.getQualifier().hasLocation() || type.isBuiltIn())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// no locations on blocks of built-in variables
|
||||||
|
if (type.isStruct()) {
|
||||||
|
if (type.getStruct()->size() < 1)
|
||||||
|
return -1;
|
||||||
|
if ((*type.getStruct())[0].type->isBuiltIn())
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// point to the right input or output location counter
|
||||||
|
int& nextLocation = type.getQualifier().isPipeInput() ? nextInputLocation : nextOutputLocation;
|
||||||
|
|
||||||
|
// Placeholder. This does not do proper cross-stage lining up, nor
|
||||||
|
// work with mixed location/no-location declarations.
|
||||||
|
int location = nextLocation;
|
||||||
|
int typeLocationSize;
|
||||||
|
// Don’t take into account the outer-most array if the stage’s
|
||||||
|
// interface is automatically an array.
|
||||||
|
if (type.getQualifier().isArrayedIo(stage)) {
|
||||||
|
TType elementType(type, 0);
|
||||||
|
typeLocationSize = TIntermediate::computeTypeLocationSize(elementType, stage);
|
||||||
|
} else {
|
||||||
|
typeLocationSize = TIntermediate::computeTypeLocationSize(type, stage);
|
||||||
|
}
|
||||||
|
nextLocation += typeLocationSize;
|
||||||
|
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void notifyBinding(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
|
||||||
|
void notifyInOut(EShLanguage, const char* /*name*/, const TType&, bool /*is_live*/) override {}
|
||||||
|
void endNotifications(EShLanguage) override {}
|
||||||
|
void beginNotifications(EShLanguage) override {}
|
||||||
|
void beginResolve(EShLanguage) override {}
|
||||||
|
void endResolve(EShLanguage) override {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const TIntermediate &intermediate;
|
||||||
|
int nextUniformLocation;
|
||||||
|
int nextInputLocation;
|
||||||
|
int nextOutputLocation;
|
||||||
|
|
||||||
|
// Return descriptor set specific base if there is one, and the generic base otherwise.
|
||||||
|
int selectBaseBinding(int base, int descriptorSetBase) const {
|
||||||
|
return descriptorSetBase != -1 ? descriptorSetBase : base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getLayoutSet(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().hasSet())
|
||||||
|
return type.getQualifier().layoutSet;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSamplerType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isTextureType(const glslang::TType& type) {
|
||||||
|
return (type.getBasicType() == glslang::EbtSampler &&
|
||||||
|
(type.getSampler().isTexture() || type.getSampler().isSubpass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isUboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqUniform;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basic implementation of glslang::TIoMapResolver that replaces the
|
||||||
|
* previous offset behavior.
|
||||||
|
* It does the same, uses the offsets for the corresponding uniform
|
||||||
|
* types. Also respects the EOptionAutoMapBindings flag and binds
|
||||||
|
* them if needed.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Default resolver
|
||||||
|
*/
|
||||||
|
struct TDefaultIoResolver : public TDefaultIoResolverBase
|
||||||
|
{
|
||||||
|
TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
|
||||||
|
|
||||||
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
||||||
|
{
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
if (isImageType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isTextureType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSsboType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
|
||||||
|
} else if (is_live && doAutoBindingMapping()) {
|
||||||
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
|
if (isImageType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResImage, set));
|
||||||
|
|
||||||
|
if (isTextureType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResTexture, set));
|
||||||
|
|
||||||
|
if (isSsboType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResSsbo, set));
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResSampler, set));
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResUbo, set));
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static bool isImageType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSsboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/********************************************************************************
|
||||||
|
The following IO resolver maps types in HLSL register space, as follows:
|
||||||
|
|
||||||
|
t - for shader resource views (SRV)
|
||||||
|
TEXTURE1D
|
||||||
|
TEXTURE1DARRAY
|
||||||
|
TEXTURE2D
|
||||||
|
TEXTURE2DARRAY
|
||||||
|
TEXTURE3D
|
||||||
|
TEXTURECUBE
|
||||||
|
TEXTURECUBEARRAY
|
||||||
|
TEXTURE2DMS
|
||||||
|
TEXTURE2DMSARRAY
|
||||||
|
STRUCTUREDBUFFER
|
||||||
|
BYTEADDRESSBUFFER
|
||||||
|
BUFFER
|
||||||
|
TBUFFER
|
||||||
|
|
||||||
|
s - for samplers
|
||||||
|
SAMPLER
|
||||||
|
SAMPLER1D
|
||||||
|
SAMPLER2D
|
||||||
|
SAMPLER3D
|
||||||
|
SAMPLERCUBE
|
||||||
|
SAMPLERSTATE
|
||||||
|
SAMPLERCOMPARISONSTATE
|
||||||
|
|
||||||
|
u - for unordered access views (UAV)
|
||||||
|
RWBYTEADDRESSBUFFER
|
||||||
|
RWSTRUCTUREDBUFFER
|
||||||
|
APPENDSTRUCTUREDBUFFER
|
||||||
|
CONSUMESTRUCTUREDBUFFER
|
||||||
|
RWBUFFER
|
||||||
|
RWTEXTURE1D
|
||||||
|
RWTEXTURE1DARRAY
|
||||||
|
RWTEXTURE2D
|
||||||
|
RWTEXTURE2DARRAY
|
||||||
|
RWTEXTURE3D
|
||||||
|
|
||||||
|
b - for constant buffer views (CBV)
|
||||||
|
CBUFFER
|
||||||
|
CONSTANTBUFFER
|
||||||
|
********************************************************************************/
|
||||||
|
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
||||||
|
{
|
||||||
|
TDefaultHlslIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
|
||||||
|
|
||||||
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
|
||||||
|
{
|
||||||
|
const int set = getLayoutSet(type);
|
||||||
|
|
||||||
|
if (type.getQualifier().hasBinding()) {
|
||||||
|
if (isUavType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSrvType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
|
||||||
|
} else if (is_live && doAutoBindingMapping()) {
|
||||||
|
// find free slot, the caller did make sure it passes all vars with binding
|
||||||
|
// first and now all are passed that do not have a binding and needs one
|
||||||
|
|
||||||
|
if (isUavType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResUav, set));
|
||||||
|
|
||||||
|
if (isSrvType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResTexture, set));
|
||||||
|
|
||||||
|
if (isSamplerType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResSampler, set));
|
||||||
|
|
||||||
|
if (isUboType(type))
|
||||||
|
return getFreeSlot(set, getBaseBinding(EResUbo, set));
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Return true if this is a SRV (shader resource view) type:
|
||||||
|
static bool isSrvType(const glslang::TType& type) {
|
||||||
|
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if this is a UAV (unordered access view) type:
|
||||||
|
static bool isUavType(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().readonly)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) ||
|
||||||
|
(type.getQualifier().storage == EvqBuffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Map I/O variables to provided offsets, and make bindings for
|
||||||
|
// unbound but live variables.
|
||||||
|
//
|
||||||
|
// Returns false if the input is too malformed to do this.
|
||||||
|
bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver)
|
||||||
|
{
|
||||||
|
bool somethingToDo = !intermediate.getResourceSetBinding().empty() ||
|
||||||
|
intermediate.getAutoMapBindings() ||
|
||||||
|
intermediate.getAutoMapLocations();
|
||||||
|
|
||||||
|
for (int res = 0; res < EResCount; ++res) {
|
||||||
|
somethingToDo = somethingToDo ||
|
||||||
|
(intermediate.getShiftBinding(TResourceType(res)) != 0) ||
|
||||||
|
intermediate.hasShiftBindingForSet(TResourceType(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!somethingToDo && resolver == nullptr)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TIntermNode* root = intermediate.getTreeRoot();
|
||||||
|
if (root == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
||||||
|
TDefaultIoResolver defaultResolver(intermediate);
|
||||||
|
TDefaultHlslIoResolver defaultHlslResolver(intermediate);
|
||||||
|
|
||||||
|
if (resolver == nullptr) {
|
||||||
|
// TODO: use a passed in IO mapper for this
|
||||||
|
if (intermediate.usingHlslIoMapping())
|
||||||
|
resolver = &defaultHlslResolver;
|
||||||
|
else
|
||||||
|
resolver = &defaultResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
|
||||||
|
TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap);
|
||||||
|
TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
|
||||||
|
|
||||||
|
root->traverse(&iter_binding_all);
|
||||||
|
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
|
||||||
|
|
||||||
|
while (!iter_binding_live.functions.empty()) {
|
||||||
|
TIntermNode* function = iter_binding_live.functions.back();
|
||||||
|
iter_binding_live.functions.pop_back();
|
||||||
|
function->traverse(&iter_binding_live);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
|
||||||
|
std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority());
|
||||||
|
|
||||||
|
bool hadError = false;
|
||||||
|
TNotifyInOutAdaptor inOutNotify(stage, *resolver);
|
||||||
|
TNotifyUniformAdaptor uniformNotify(stage, *resolver);
|
||||||
|
TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate);
|
||||||
|
TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate);
|
||||||
|
resolver->beginNotifications(stage);
|
||||||
|
std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify);
|
||||||
|
std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify);
|
||||||
|
std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify);
|
||||||
|
resolver->endNotifications(stage);
|
||||||
|
resolver->beginResolve(stage);
|
||||||
|
std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve);
|
||||||
|
std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve);
|
||||||
|
std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve);
|
||||||
|
resolver->endResolve(stage);
|
||||||
|
|
||||||
|
if (!hadError) {
|
||||||
|
// sort by id again, so we can use lower bound to find entries
|
||||||
|
std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderById());
|
||||||
|
TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap);
|
||||||
|
root->traverse(&iter_iomap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !hadError;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace glslang
|
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2016 LunarG, 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 _IOMAPPER_INCLUDED
|
||||||
|
#define _IOMAPPER_INCLUDED
|
||||||
|
|
||||||
|
#include "../Public/ShaderLang.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
||||||
|
//
|
||||||
|
|
||||||
|
class TInfoSink;
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
class TIntermediate;
|
||||||
|
|
||||||
|
// I/O mapper
|
||||||
|
class TIoMapper {
|
||||||
|
public:
|
||||||
|
TIoMapper() {}
|
||||||
|
virtual ~TIoMapper() {}
|
||||||
|
|
||||||
|
// grow the reflection stage by stage
|
||||||
|
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // _IOMAPPER_INCLUDED
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -60,6 +61,13 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message)
|
||||||
++numErrors;
|
++numErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Link-time warning.
|
||||||
|
void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
||||||
|
{
|
||||||
|
infoSink.info.prefix(EPrefixWarning);
|
||||||
|
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
|
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
|
||||||
// name must have the exact same set of members qualified with offset and their integral-constant
|
// name must have the exact same set of members qualified with offset and their integral-constant
|
||||||
// expression values must be the same, or a link-time error results."
|
// expression values must be the same, or a link-time error results."
|
||||||
|
@ -75,23 +83,28 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
if (source != unit.source)
|
if (source != unit.source)
|
||||||
error(infoSink, "can't link compilation units from different source languages");
|
error(infoSink, "can't link compilation units from different source languages");
|
||||||
|
|
||||||
if (source == EShSourceHlsl && unit.entryPoint.size() > 0) {
|
if (unit.getNumEntryPoints() > 0) {
|
||||||
if (entryPoint.size() > 0)
|
if (getNumEntryPoints() > 0)
|
||||||
error(infoSink, "can't handle multiple entry points per stage");
|
error(infoSink, "can't handle multiple entry points per stage");
|
||||||
else
|
else {
|
||||||
entryPoint = unit.entryPoint;
|
entryPointName = unit.getEntryPointName();
|
||||||
|
entryPointMangledName = unit.getEntryPointMangledName();
|
||||||
}
|
}
|
||||||
numMains += unit.numMains;
|
}
|
||||||
numErrors += unit.numErrors;
|
numEntryPoints += unit.getNumEntryPoints();
|
||||||
|
numErrors += unit.getNumErrors();
|
||||||
numPushConstants += unit.numPushConstants;
|
numPushConstants += unit.numPushConstants;
|
||||||
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
|
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
|
||||||
|
|
||||||
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
||||||
error(infoSink, "gl_FragCoord redeclarations must match across shaders\n");
|
error(infoSink, "gl_FragCoord redeclarations must match across shaders");
|
||||||
|
|
||||||
if (! earlyFragmentTests)
|
if (! earlyFragmentTests)
|
||||||
earlyFragmentTests = unit.earlyFragmentTests;
|
earlyFragmentTests = unit.earlyFragmentTests;
|
||||||
|
|
||||||
|
if (!postDepthCoverage)
|
||||||
|
postDepthCoverage = unit.postDepthCoverage;
|
||||||
|
|
||||||
if (depthLayout == EldNone)
|
if (depthLayout == EldNone)
|
||||||
depthLayout = unit.depthLayout;
|
depthLayout = unit.depthLayout;
|
||||||
else if (depthLayout != unit.depthLayout)
|
else if (depthLayout != unit.depthLayout)
|
||||||
|
@ -255,10 +268,13 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
|
||||||
// Recursively merge the implicit array sizes through the objects' respective type trees.
|
// Recursively merge the implicit array sizes through the objects' respective type trees.
|
||||||
void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
|
void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
|
||||||
{
|
{
|
||||||
if (type.isImplicitlySizedArray() && unitType.isArray()) {
|
if (type.isUnsizedArray()) {
|
||||||
int newImplicitArraySize = unitType.isImplicitlySizedArray() ? unitType.getImplicitArraySize() : unitType.getOuterArraySize();
|
if (unitType.isUnsizedArray()) {
|
||||||
if (newImplicitArraySize > type.getImplicitArraySize ())
|
type.updateImplicitArraySize(unitType.getImplicitArraySize());
|
||||||
type.setImplicitArraySize(newImplicitArraySize);
|
if (unitType.isArrayVariablyIndexed())
|
||||||
|
type.setArrayVariablyIndexed();
|
||||||
|
} else if (unitType.isSizedArray())
|
||||||
|
type.changeOuterArraySize(unitType.getOuterArraySize());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type mismatches are caught and reported after this, just be careful for now.
|
// Type mismatches are caught and reported after this, just be careful for now.
|
||||||
|
@ -281,9 +297,14 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||||
|
|
||||||
// Types have to match
|
// Types have to match
|
||||||
if (symbol.getType() != unitSymbol.getType()) {
|
if (symbol.getType() != unitSymbol.getType()) {
|
||||||
|
// but, we make an exception if one is an implicit array and the other is sized
|
||||||
|
if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
|
||||||
|
symbol.getType().sameElementType(unitSymbol.getType()) &&
|
||||||
|
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) {
|
||||||
error(infoSink, "Types must match:");
|
error(infoSink, "Types must match:");
|
||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Qualifiers have to (almost) match
|
// Qualifiers have to (almost) match
|
||||||
|
|
||||||
|
@ -368,16 +389,24 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
||||||
//
|
//
|
||||||
// Also, lock in defaults of things not set, including array sizes.
|
// Also, lock in defaults of things not set, including array sizes.
|
||||||
//
|
//
|
||||||
void TIntermediate::finalCheck(TInfoSink& infoSink)
|
void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
||||||
{
|
{
|
||||||
if (source == EShSourceGlsl && numMains < 1)
|
if (getTreeRoot() == nullptr)
|
||||||
error(infoSink, "Missing entry point: Each stage requires one \"void main()\" entry point");
|
return;
|
||||||
|
|
||||||
|
if (numEntryPoints < 1) {
|
||||||
|
if (source == EShSourceGlsl)
|
||||||
|
error(infoSink, "Missing entry point: Each stage requires one entry point");
|
||||||
|
else
|
||||||
|
warn(infoSink, "Entry point not found");
|
||||||
|
}
|
||||||
|
|
||||||
if (numPushConstants > 1)
|
if (numPushConstants > 1)
|
||||||
error(infoSink, "Only one push_constant block is allowed per stage");
|
error(infoSink, "Only one push_constant block is allowed per stage");
|
||||||
|
|
||||||
// recursion checking
|
// recursion and missing body checking
|
||||||
checkCallGraphCycles(infoSink);
|
checkCallGraphCycles(infoSink);
|
||||||
|
checkCallGraphBodies(infoSink, keepUncalled);
|
||||||
|
|
||||||
// overlap/alias/missing I/O, etc.
|
// overlap/alias/missing I/O, etc.
|
||||||
inOutLocationCheck(infoSink);
|
inOutLocationCheck(infoSink);
|
||||||
|
@ -442,22 +471,37 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
|
||||||
error(infoSink, "At least one shader must specify an output layout(vertices=...)");
|
error(infoSink, "At least one shader must specify an output layout(vertices=...)");
|
||||||
break;
|
break;
|
||||||
case EShLangTessEvaluation:
|
case EShLangTessEvaluation:
|
||||||
|
if (source == EShSourceGlsl) {
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
error(infoSink, "At least one shader must specify an input layout primitive");
|
error(infoSink, "At least one shader must specify an input layout primitive");
|
||||||
if (vertexSpacing == EvsNone)
|
if (vertexSpacing == EvsNone)
|
||||||
vertexSpacing = EvsEqual;
|
vertexSpacing = EvsEqual;
|
||||||
if (vertexOrder == EvoNone)
|
if (vertexOrder == EvoNone)
|
||||||
vertexOrder = EvoCcw;
|
vertexOrder = EvoCcw;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EShLangGeometry:
|
case EShLangGeometry:
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
error(infoSink, "At least one shader must specify an input layout primitive");
|
error(infoSink, "At least one shader must specify an input layout primitive");
|
||||||
if (outputPrimitive == ElgNone)
|
if (outputPrimitive == ElgNone
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
&& !getGeoPassthroughEXT()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
error(infoSink, "At least one shader must specify an output layout primitive");
|
error(infoSink, "At least one shader must specify an output layout primitive");
|
||||||
if (vertices == TQualifier::layoutNotSet)
|
if (vertices == TQualifier::layoutNotSet
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
&& !getGeoPassthroughEXT()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
|
error(infoSink, "At least one shader must specify a layout(max_vertices = value)");
|
||||||
break;
|
break;
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
|
// for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in
|
||||||
|
// ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage
|
||||||
|
// requiring explicit early_fragment_tests
|
||||||
|
if (getPostDepthCoverage() && !getEarlyFragmentTests())
|
||||||
|
error(infoSink, "post_depth_coverage requires early_fragment_tests");
|
||||||
break;
|
break;
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
break;
|
break;
|
||||||
|
@ -475,7 +519,9 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
|
||||||
virtual void visitSymbol(TIntermSymbol* symbol)
|
virtual void visitSymbol(TIntermSymbol* symbol)
|
||||||
{
|
{
|
||||||
// Implicitly size arrays.
|
// Implicitly size arrays.
|
||||||
symbol->getWritableType().adoptImplicitArraySizes();
|
// If an unsized array is left as unsized, it effectively
|
||||||
|
// becomes run-time sized.
|
||||||
|
symbol->getWritableType().adoptImplicitArraySizes(false);
|
||||||
}
|
}
|
||||||
} finalLinkTraverser;
|
} finalLinkTraverser;
|
||||||
|
|
||||||
|
@ -488,7 +534,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
|
||||||
//
|
//
|
||||||
void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
|
void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
|
||||||
{
|
{
|
||||||
// Reset everything, once.
|
// Clear fields we'll use for this.
|
||||||
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
|
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
|
||||||
call->visited = false;
|
call->visited = false;
|
||||||
call->currentPath = false;
|
call->currentPath = false;
|
||||||
|
@ -563,6 +609,85 @@ void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
|
||||||
} while (newRoot); // redundant loop check; should always exit via the 'break' above
|
} while (newRoot); // redundant loop check; should always exit via the 'break' above
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// See which functions are reachable from the entry point and which have bodies.
|
||||||
|
// Reachable ones with missing bodies are errors.
|
||||||
|
// Unreachable bodies are dead code.
|
||||||
|
//
|
||||||
|
void TIntermediate::checkCallGraphBodies(TInfoSink& infoSink, bool keepUncalled)
|
||||||
|
{
|
||||||
|
// Clear fields we'll use for this.
|
||||||
|
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
|
||||||
|
call->visited = false;
|
||||||
|
call->calleeBodyPosition = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The top level of the AST includes function definitions (bodies).
|
||||||
|
// Compare these to function calls in the call graph.
|
||||||
|
// We'll end up knowing which have bodies, and if so,
|
||||||
|
// how to map the call-graph node to the location in the AST.
|
||||||
|
TIntermSequence &functionSequence = getTreeRoot()->getAsAggregate()->getSequence();
|
||||||
|
std::vector<bool> reachable(functionSequence.size(), true); // so that non-functions are reachable
|
||||||
|
for (int f = 0; f < (int)functionSequence.size(); ++f) {
|
||||||
|
glslang::TIntermAggregate* node = functionSequence[f]->getAsAggregate();
|
||||||
|
if (node && (node->getOp() == glslang::EOpFunction)) {
|
||||||
|
if (node->getName().compare(getEntryPointMangledName().c_str()) != 0)
|
||||||
|
reachable[f] = false; // so that function bodies are unreachable, until proven otherwise
|
||||||
|
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
|
||||||
|
if (call->callee == node->getName())
|
||||||
|
call->calleeBodyPosition = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start call-graph traversal by visiting the entry point nodes.
|
||||||
|
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
|
||||||
|
if (call->caller.compare(getEntryPointMangledName().c_str()) == 0)
|
||||||
|
call->visited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Propagate 'visited' through the call-graph to every part of the graph it
|
||||||
|
// can reach (seeded with the entry-point setting above).
|
||||||
|
bool changed;
|
||||||
|
do {
|
||||||
|
changed = false;
|
||||||
|
for (auto call1 = callGraph.begin(); call1 != callGraph.end(); ++call1) {
|
||||||
|
if (call1->visited) {
|
||||||
|
for (TGraph::iterator call2 = callGraph.begin(); call2 != callGraph.end(); ++call2) {
|
||||||
|
if (! call2->visited) {
|
||||||
|
if (call1->callee == call2->caller) {
|
||||||
|
changed = true;
|
||||||
|
call2->visited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (changed);
|
||||||
|
|
||||||
|
// Any call-graph node set to visited but without a callee body is an error.
|
||||||
|
for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) {
|
||||||
|
if (call->visited) {
|
||||||
|
if (call->calleeBodyPosition == -1) {
|
||||||
|
error(infoSink, "No function definition (body) found: ");
|
||||||
|
infoSink.info << " " << call->callee << "\n";
|
||||||
|
} else
|
||||||
|
reachable[call->calleeBodyPosition] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bodies in the AST not reached by the call graph are dead;
|
||||||
|
// clear them out, since they can't be reached and also can't
|
||||||
|
// be translated further due to possibility of being ill defined.
|
||||||
|
if (! keepUncalled) {
|
||||||
|
for (int f = 0; f < (int)functionSequence.size(); ++f) {
|
||||||
|
if (! reachable[f])
|
||||||
|
functionSequence[f] = nullptr;
|
||||||
|
}
|
||||||
|
functionSequence.erase(std::remove(functionSequence.begin(), functionSequence.end(), nullptr), functionSequence.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Satisfy rules for location qualifiers on inputs and outputs
|
// Satisfy rules for location qualifiers on inputs and outputs
|
||||||
//
|
//
|
||||||
|
@ -651,7 +776,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
||||||
|
|
||||||
int size;
|
int size;
|
||||||
if (qualifier.isUniformOrBuffer()) {
|
if (qualifier.isUniformOrBuffer()) {
|
||||||
if (type.isArray())
|
if (type.isSizedArray())
|
||||||
size = type.getCumulativeArraySize();
|
size = type.getCumulativeArraySize();
|
||||||
else
|
else
|
||||||
size = 1;
|
size = 1;
|
||||||
|
@ -659,39 +784,102 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
||||||
// Strip off the outer array dimension for those having an extra one.
|
// Strip off the outer array dimension for those having an extra one.
|
||||||
if (type.isArray() && qualifier.isArrayedIo(language)) {
|
if (type.isArray() && qualifier.isArrayedIo(language)) {
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
size = computeTypeLocationSize(elementType);
|
size = computeTypeLocationSize(elementType, language);
|
||||||
} else
|
} else
|
||||||
size = computeTypeLocationSize(type);
|
size = computeTypeLocationSize(type, language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Locations, and components within locations.
|
||||||
|
//
|
||||||
|
// Almost always, dealing with components means a single location is involved.
|
||||||
|
// The exception is a dvec3. From the spec:
|
||||||
|
//
|
||||||
|
// "A dvec3 will consume all four components of the first location and components 0 and 1 of
|
||||||
|
// the second location. This leaves components 2 and 3 available for other component-qualified
|
||||||
|
// declarations."
|
||||||
|
//
|
||||||
|
// That means, without ever mentioning a component, a component range
|
||||||
|
// for a different location gets specified, if it's not a vertex shader input. (!)
|
||||||
|
// (A vertex shader input will show using only one location, even for a dvec3/4.)
|
||||||
|
//
|
||||||
|
// So, for the case of dvec3, we need two independent ioRanges.
|
||||||
|
|
||||||
|
int collision = -1; // no collision
|
||||||
|
if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
|
||||||
|
(qualifier.isPipeInput() || qualifier.isPipeOutput())) {
|
||||||
|
// Dealing with dvec3 in/out split across two locations.
|
||||||
|
// Need two io-ranges.
|
||||||
|
// The case where the dvec3 doesn't start at component 0 was previously caught as overflow.
|
||||||
|
|
||||||
|
// First range:
|
||||||
|
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
|
||||||
|
TRange componentRange(0, 3);
|
||||||
|
TIoRange range(locationRange, componentRange, type.getBasicType(), 0);
|
||||||
|
|
||||||
|
// check for collisions
|
||||||
|
collision = checkLocationRange(set, range, type, typeCollision);
|
||||||
|
if (collision < 0) {
|
||||||
|
usedIo[set].push_back(range);
|
||||||
|
|
||||||
|
// Second range:
|
||||||
|
TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
|
||||||
|
TRange componentRange2(0, 1);
|
||||||
|
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0);
|
||||||
|
|
||||||
|
// check for collisions
|
||||||
|
collision = checkLocationRange(set, range2, type, typeCollision);
|
||||||
|
if (collision < 0)
|
||||||
|
usedIo[set].push_back(range2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not a dvec3 in/out split across two locations, generic path.
|
||||||
|
// Need a single IO-range block.
|
||||||
|
|
||||||
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1);
|
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1);
|
||||||
TRange componentRange(0, 3);
|
TRange componentRange(0, 3);
|
||||||
if (qualifier.hasComponent()) {
|
if (qualifier.hasComponent() || type.getVectorSize() > 0) {
|
||||||
|
int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1);
|
||||||
|
if (qualifier.hasComponent())
|
||||||
componentRange.start = qualifier.layoutComponent;
|
componentRange.start = qualifier.layoutComponent;
|
||||||
componentRange.last = componentRange.start + type.getVectorSize() - 1;
|
componentRange.last = componentRange.start + consumedComponents - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// combine location and component ranges
|
||||||
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);
|
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);
|
||||||
|
|
||||||
// check for collisions, except for vertex inputs on desktop
|
// check for collisions, except for vertex inputs on desktop targeting OpenGL
|
||||||
if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput())) {
|
if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
|
||||||
|
collision = checkLocationRange(set, range, type, typeCollision);
|
||||||
|
|
||||||
|
if (collision < 0)
|
||||||
|
usedIo[set].push_back(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
return collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare a new (the passed in) 'range' against the existing set, and see
|
||||||
|
// if there are any collisions.
|
||||||
|
//
|
||||||
|
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
||||||
|
//
|
||||||
|
int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TType& type, bool& typeCollision)
|
||||||
|
{
|
||||||
for (size_t r = 0; r < usedIo[set].size(); ++r) {
|
for (size_t r = 0; r < usedIo[set].size(); ++r) {
|
||||||
if (range.overlap(usedIo[set][r])) {
|
if (range.overlap(usedIo[set][r])) {
|
||||||
// there is a collision; pick one
|
// there is a collision; pick one
|
||||||
return std::max(locationRange.start, usedIo[set][r].location.start);
|
return std::max(range.location.start, usedIo[set][r].location.start);
|
||||||
} else if (locationRange.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
|
} else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
|
||||||
// aliased-type mismatch
|
// aliased-type mismatch
|
||||||
typeCollision = true;
|
typeCollision = true;
|
||||||
return std::max(locationRange.start, usedIo[set][r].location.start);
|
return std::max(range.location.start, usedIo[set][r].location.start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
usedIo[set].push_back(range);
|
|
||||||
|
|
||||||
return -1; // no collision
|
return -1; // no collision
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
|
// Accumulate bindings and offsets, and check for collisions
|
||||||
// as the accumulation is done.
|
// as the accumulation is done.
|
||||||
//
|
//
|
||||||
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
||||||
|
@ -730,18 +918,18 @@ bool TIntermediate::addUsedConstantId(int id)
|
||||||
|
|
||||||
// Recursively figure out how many locations are used up by an input or output type.
|
// Recursively figure out how many locations are used up by an input or output type.
|
||||||
// Return the size of type, as measured by "locations".
|
// Return the size of type, as measured by "locations".
|
||||||
int TIntermediate::computeTypeLocationSize(const TType& type) const
|
int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage)
|
||||||
{
|
{
|
||||||
// "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n
|
// "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n
|
||||||
// consecutive locations..."
|
// consecutive locations..."
|
||||||
if (type.isArray()) {
|
if (type.isArray()) {
|
||||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
|
// TODO: are there valid cases of having an unsized array with a location? If so, running this code too early.
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
if (type.isImplicitlySizedArray()) {
|
if (type.isSizedArray())
|
||||||
// TODO: are there valid cases of having an implicitly-sized array with a location? If so, running this code too early.
|
return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
|
||||||
return computeTypeLocationSize(elementType);
|
else
|
||||||
} else
|
return computeTypeLocationSize(elementType, stage);
|
||||||
return type.getOuterArraySize() * computeTypeLocationSize(elementType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// "The locations consumed by block and structure members are determined by applying the rules above
|
// "The locations consumed by block and structure members are determined by applying the rules above
|
||||||
|
@ -750,7 +938,7 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
||||||
TType memberType(type, member);
|
TType memberType(type, member);
|
||||||
size += computeTypeLocationSize(memberType);
|
size += computeTypeLocationSize(memberType, stage);
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -764,7 +952,7 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
|
||||||
if (type.isScalar())
|
if (type.isScalar())
|
||||||
return 1;
|
return 1;
|
||||||
if (type.isVector()) {
|
if (type.isVector()) {
|
||||||
if (language == EShLangVertex && type.getQualifier().isPipeInput())
|
if (stage == EShLangVertex && type.getQualifier().isPipeInput())
|
||||||
return 1;
|
return 1;
|
||||||
if (type.getBasicType() == EbtDouble && type.getVectorSize() > 2)
|
if (type.getBasicType() == EbtDouble && type.getVectorSize() > 2)
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -777,13 +965,44 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
|
||||||
// for an n-element array of m-component vectors..."
|
// for an n-element array of m-component vectors..."
|
||||||
if (type.isMatrix()) {
|
if (type.isMatrix()) {
|
||||||
TType columnType(type, 0);
|
TType columnType(type, 0);
|
||||||
return type.getMatrixCols() * computeTypeLocationSize(columnType);
|
return type.getMatrixCols() * computeTypeLocationSize(columnType, stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same as computeTypeLocationSize but for uniforms
|
||||||
|
int TIntermediate::computeTypeUniformLocationSize(const TType& type)
|
||||||
|
{
|
||||||
|
// "Individual elements of a uniform array are assigned
|
||||||
|
// consecutive locations with the first element taking location
|
||||||
|
// location."
|
||||||
|
if (type.isArray()) {
|
||||||
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
|
TType elementType(type, 0);
|
||||||
|
if (type.isSizedArray()) {
|
||||||
|
return type.getOuterArraySize() * computeTypeUniformLocationSize(elementType);
|
||||||
|
} else {
|
||||||
|
// TODO: are there valid cases of having an implicitly-sized array with a location? If so, running this code too early.
|
||||||
|
return computeTypeUniformLocationSize(elementType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// "Each subsequent inner-most member or element gets incremental
|
||||||
|
// locations for the entire structure or array."
|
||||||
|
if (type.isStruct()) {
|
||||||
|
int size = 0;
|
||||||
|
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
||||||
|
TType memberType(type, member);
|
||||||
|
size += computeTypeUniformLocationSize(memberType);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Accumulate xfb buffer ranges and check for collisions as the accumulation is done.
|
// Accumulate xfb buffer ranges and check for collisions as the accumulation is done.
|
||||||
//
|
//
|
||||||
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
||||||
|
@ -828,7 +1047,7 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
||||||
|
|
||||||
if (type.isArray()) {
|
if (type.isArray()) {
|
||||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
assert(type.isExplicitlySizedArray());
|
assert(type.isSizedArray());
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble);
|
return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble);
|
||||||
}
|
}
|
||||||
|
@ -878,15 +1097,20 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
||||||
|
|
||||||
const int baseAlignmentVec4Std140 = 16;
|
const int baseAlignmentVec4Std140 = 16;
|
||||||
|
|
||||||
// Return the size and alignment of a scalar.
|
// Return the size and alignment of a component of the given type.
|
||||||
// The size is returned in the 'size' parameter
|
// The size is returned in the 'size' parameter
|
||||||
// Return value is the alignment of the type.
|
// Return value is the alignment..
|
||||||
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
||||||
{
|
{
|
||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
case EbtDouble: size = 8; return 8;
|
case EbtDouble: size = 8; return 8;
|
||||||
|
case EbtFloat16: size = 2; return 2;
|
||||||
|
case EbtInt8:
|
||||||
|
case EbtUint8: size = 1; return 1;
|
||||||
|
case EbtInt16:
|
||||||
|
case EbtUint16: size = 2; return 2;
|
||||||
default: size = 4; return 4;
|
default: size = 4; return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -940,7 +1164,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||||
// components each, according to rule (4).
|
// components each, according to rule (4).
|
||||||
//
|
//
|
||||||
// 6. If the member is an array of S column-major matrices with C columns and
|
// 6. If the member is an array of S column-major matrices with C columns and
|
||||||
// R rows, the matrix is stored identically to a row of S C column vectors
|
// R rows, the matrix is stored identically to a row of S X C column vectors
|
||||||
// with R components each, according to rule (4).
|
// with R components each, according to rule (4).
|
||||||
//
|
//
|
||||||
// 7. If the member is a row-major matrix with C columns and R rows, the matrix
|
// 7. If the member is a row-major matrix with C columns and R rows, the matrix
|
||||||
|
@ -948,7 +1172,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||||
// according to rule (4).
|
// according to rule (4).
|
||||||
//
|
//
|
||||||
// 8. If the member is an array of S row-major matrices with C columns and R
|
// 8. If the member is an array of S row-major matrices with C columns and R
|
||||||
// rows, the matrix is stored identically to a row of S R row vectors with C
|
// rows, the matrix is stored identically to a row of S X R row vectors with C
|
||||||
// components each, according to rule (4).
|
// components each, according to rule (4).
|
||||||
//
|
//
|
||||||
// 9. If the member is a structure, the base alignment of the structure is N , where
|
// 9. If the member is a structure, the base alignment of the structure is N , where
|
||||||
|
@ -1015,6 +1239,8 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||||
if (type.isVector()) {
|
if (type.isVector()) {
|
||||||
int scalarAlign = getBaseAlignmentScalar(type, size);
|
int scalarAlign = getBaseAlignmentScalar(type, size);
|
||||||
switch (type.getVectorSize()) {
|
switch (type.getVectorSize()) {
|
||||||
|
case 1: // HLSL has this, GLSL does not
|
||||||
|
return scalarAlign;
|
||||||
case 2:
|
case 2:
|
||||||
size *= 2;
|
size *= 2;
|
||||||
return 2 * scalarAlign;
|
return 2 * scalarAlign;
|
||||||
|
@ -1047,4 +1273,14 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
||||||
return baseAlignmentVec4Std140;
|
return baseAlignmentVec4Std140;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To aid the basic HLSL rule about crossing vec4 boundaries.
|
||||||
|
bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
|
||||||
|
{
|
||||||
|
if (! type.isVector() || type.isArray())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return size <= 16 ? offset / 16 != (offset + size - 1) / 16
|
||||||
|
: offset % 16 != 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
449
Externals/glslang/glslang/MachineIndependent/localintermediate.h
vendored
Normal file → Executable file
449
Externals/glslang/glslang/MachineIndependent/localintermediate.h
vendored
Normal file → Executable file
|
@ -1,10 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// Copyright (C) 2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef _LOCAL_INTERMEDIATE_INCLUDED_
|
#ifndef _LOCAL_INTERMEDIATE_INCLUDED_
|
||||||
|
@ -41,14 +43,46 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
class TInfoSink;
|
class TInfoSink;
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
struct TVectorFields {
|
struct TMatrixSelector {
|
||||||
int offsets[4];
|
int coord1; // stay agnostic about column/row; this is parse order
|
||||||
int num;
|
int coord2;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int TVectorSelector;
|
||||||
|
|
||||||
|
const int MaxSwizzleSelectors = 4;
|
||||||
|
|
||||||
|
template<typename selectorType>
|
||||||
|
class TSwizzleSelectors {
|
||||||
|
public:
|
||||||
|
TSwizzleSelectors() : size_(0) { }
|
||||||
|
|
||||||
|
void push_back(selectorType comp)
|
||||||
|
{
|
||||||
|
if (size_ < MaxSwizzleSelectors)
|
||||||
|
components[size_++] = comp;
|
||||||
|
}
|
||||||
|
void resize(int s)
|
||||||
|
{
|
||||||
|
assert(s <= size_);
|
||||||
|
size_ = s;
|
||||||
|
}
|
||||||
|
int size() const { return size_; }
|
||||||
|
selectorType operator[](int i) const
|
||||||
|
{
|
||||||
|
assert(i < MaxSwizzleSelectors);
|
||||||
|
return components[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int size_;
|
||||||
|
selectorType components[MaxSwizzleSelectors];
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -56,7 +90,9 @@ struct TVectorFields {
|
||||||
// by TIntermediate.
|
// by TIntermediate.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Used for detecting recursion: A "call" is a pair: <caller, callee>.
|
// Used for call-graph algorithms for detecting recursion, missing bodies, and dead bodies.
|
||||||
|
// A "call" is a pair: <caller, callee>.
|
||||||
|
// There can be duplicates. General assumption is the list is small.
|
||||||
struct TCall {
|
struct TCall {
|
||||||
TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { }
|
TCall(const TString& pCaller, const TString& pCallee) : caller(pCaller), callee(pCallee) { }
|
||||||
TString caller;
|
TString caller;
|
||||||
|
@ -64,6 +100,7 @@ struct TCall {
|
||||||
bool visited;
|
bool visited;
|
||||||
bool currentPath;
|
bool currentPath;
|
||||||
bool errorGiven;
|
bool errorGiven;
|
||||||
|
int calleeBodyPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A generic 1-D range.
|
// A generic 1-D range.
|
||||||
|
@ -115,6 +152,54 @@ struct TXfbBuffer {
|
||||||
bool containsDouble;
|
bool containsDouble;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Track a set of strings describing how the module was processed.
|
||||||
|
// Using the form:
|
||||||
|
// process arg0 arg1 arg2 ...
|
||||||
|
// process arg0 arg1 arg2 ...
|
||||||
|
// where everything is textual, and there can be zero or more arguments
|
||||||
|
class TProcesses {
|
||||||
|
public:
|
||||||
|
TProcesses() {}
|
||||||
|
~TProcesses() {}
|
||||||
|
|
||||||
|
void addProcess(const char* process)
|
||||||
|
{
|
||||||
|
processes.push_back(process);
|
||||||
|
}
|
||||||
|
void addProcess(const std::string& process)
|
||||||
|
{
|
||||||
|
processes.push_back(process);
|
||||||
|
}
|
||||||
|
void addArgument(int arg)
|
||||||
|
{
|
||||||
|
processes.back().append(" ");
|
||||||
|
std::string argString = std::to_string(arg);
|
||||||
|
processes.back().append(argString);
|
||||||
|
}
|
||||||
|
void addArgument(const char* arg)
|
||||||
|
{
|
||||||
|
processes.back().append(" ");
|
||||||
|
processes.back().append(arg);
|
||||||
|
}
|
||||||
|
void addArgument(const std::string& arg)
|
||||||
|
{
|
||||||
|
processes.back().append(" ");
|
||||||
|
processes.back().append(arg);
|
||||||
|
}
|
||||||
|
void addIfNonZero(const char* process, int value)
|
||||||
|
{
|
||||||
|
if (value != 0) {
|
||||||
|
addProcess(process);
|
||||||
|
addArgument(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& getProcesses() const { return processes; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::string> processes;
|
||||||
|
};
|
||||||
|
|
||||||
class TSymbolTable;
|
class TSymbolTable;
|
||||||
class TSymbol;
|
class TSymbol;
|
||||||
class TVariable;
|
class TVariable;
|
||||||
|
@ -125,12 +210,31 @@ class TVariable;
|
||||||
class TIntermediate {
|
class TIntermediate {
|
||||||
public:
|
public:
|
||||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
||||||
source(EShSourceNone), language(l), profile(p), version(v), treeRoot(0),
|
implicitThisName("@this"), implicitCounterName("@count"),
|
||||||
numMains(0), numErrors(0), numPushConstants(0), recursive(false),
|
language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0),
|
||||||
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||||
|
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
||||||
|
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
||||||
pixelCenterInteger(false), originUpperLeft(false),
|
pixelCenterInteger(false), originUpperLeft(false),
|
||||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false), depthLayout(EldNone), depthReplacing(false), blendEquations(0),
|
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
|
||||||
multiStream(false), xfbMode(false)
|
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
|
||||||
|
hlslFunctionality1(false),
|
||||||
|
blendEquations(0), xfbMode(false), multiStream(false),
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
layoutOverrideCoverage(false),
|
||||||
|
geoPassthroughEXT(false),
|
||||||
|
#endif
|
||||||
|
autoMapBindings(false),
|
||||||
|
autoMapLocations(false),
|
||||||
|
invertY(false),
|
||||||
|
flattenUniformArrays(false),
|
||||||
|
useUnknownFormat(false),
|
||||||
|
hlslOffsets(false),
|
||||||
|
useStorageBuffer(false),
|
||||||
|
hlslIoMapping(false),
|
||||||
|
textureSamplerTransformMode(EShTexSampTransKeep),
|
||||||
|
needToLegalize(false),
|
||||||
|
binaryDoubleOutput(false)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
|
@ -139,6 +243,8 @@ public:
|
||||||
localSizeSpecId[1] = TQualifier::layoutNotSet;
|
localSizeSpecId[1] = TQualifier::layoutNotSet;
|
||||||
localSizeSpecId[2] = TQualifier::layoutNotSet;
|
localSizeSpecId[2] = TQualifier::layoutNotSet;
|
||||||
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
|
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
|
||||||
|
|
||||||
|
shiftBinding.fill(0);
|
||||||
}
|
}
|
||||||
void setLimits(const TBuiltInResource& r) { resources = r; }
|
void setLimits(const TBuiltInResource& r) { resources = r; }
|
||||||
|
|
||||||
|
@ -148,13 +254,147 @@ public:
|
||||||
|
|
||||||
void setSource(EShSource s) { source = s; }
|
void setSource(EShSource s) { source = s; }
|
||||||
EShSource getSource() const { return source; }
|
EShSource getSource() const { return source; }
|
||||||
void setEntryPoint(const char* ep) { entryPoint = ep; }
|
void setEntryPointName(const char* ep)
|
||||||
const std::string& getEntryPoint() const { return entryPoint; }
|
{
|
||||||
|
entryPointName = ep;
|
||||||
|
processes.addProcess("entry-point");
|
||||||
|
processes.addArgument(entryPointName);
|
||||||
|
}
|
||||||
|
void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
|
||||||
|
const std::string& getEntryPointName() const { return entryPointName; }
|
||||||
|
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
|
||||||
|
|
||||||
|
void setShiftBinding(TResourceType res, unsigned int shift)
|
||||||
|
{
|
||||||
|
shiftBinding[res] = shift;
|
||||||
|
|
||||||
|
const char* name = getResourceName(res);
|
||||||
|
if (name != nullptr)
|
||||||
|
processes.addIfNonZero(name, shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
|
||||||
|
|
||||||
|
void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
|
||||||
|
{
|
||||||
|
if (shift == 0) // ignore if there's no shift: it's a no-op.
|
||||||
|
return;
|
||||||
|
|
||||||
|
shiftBindingForSet[res][set] = shift;
|
||||||
|
|
||||||
|
const char* name = getResourceName(res);
|
||||||
|
if (name != nullptr) {
|
||||||
|
processes.addProcess(name);
|
||||||
|
processes.addArgument(shift);
|
||||||
|
processes.addArgument(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getShiftBindingForSet(TResourceType res, unsigned int set) const
|
||||||
|
{
|
||||||
|
const auto shift = shiftBindingForSet[res].find(set);
|
||||||
|
return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
|
||||||
|
}
|
||||||
|
bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
|
||||||
|
|
||||||
|
void setResourceSetBinding(const std::vector<std::string>& shift)
|
||||||
|
{
|
||||||
|
resourceSetBinding = shift;
|
||||||
|
if (shift.size() > 0) {
|
||||||
|
processes.addProcess("resource-set-binding");
|
||||||
|
for (int s = 0; s < (int)shift.size(); ++s)
|
||||||
|
processes.addArgument(shift[s]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
|
||||||
|
void setAutoMapBindings(bool map)
|
||||||
|
{
|
||||||
|
autoMapBindings = map;
|
||||||
|
if (autoMapBindings)
|
||||||
|
processes.addProcess("auto-map-bindings");
|
||||||
|
}
|
||||||
|
bool getAutoMapBindings() const { return autoMapBindings; }
|
||||||
|
void setAutoMapLocations(bool map)
|
||||||
|
{
|
||||||
|
autoMapLocations = map;
|
||||||
|
if (autoMapLocations)
|
||||||
|
processes.addProcess("auto-map-locations");
|
||||||
|
}
|
||||||
|
bool getAutoMapLocations() const { return autoMapLocations; }
|
||||||
|
void setInvertY(bool invert)
|
||||||
|
{
|
||||||
|
invertY = invert;
|
||||||
|
if (invertY)
|
||||||
|
processes.addProcess("invert-y");
|
||||||
|
}
|
||||||
|
bool getInvertY() const { return invertY; }
|
||||||
|
|
||||||
|
void setFlattenUniformArrays(bool flatten)
|
||||||
|
{
|
||||||
|
flattenUniformArrays = flatten;
|
||||||
|
if (flattenUniformArrays)
|
||||||
|
processes.addProcess("flatten-uniform-arrays");
|
||||||
|
}
|
||||||
|
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
||||||
|
void setNoStorageFormat(bool b)
|
||||||
|
{
|
||||||
|
useUnknownFormat = b;
|
||||||
|
if (useUnknownFormat)
|
||||||
|
processes.addProcess("no-storage-format");
|
||||||
|
}
|
||||||
|
bool getNoStorageFormat() const { return useUnknownFormat; }
|
||||||
|
void setHlslOffsets()
|
||||||
|
{
|
||||||
|
hlslOffsets = true;
|
||||||
|
if (hlslOffsets)
|
||||||
|
processes.addProcess("hlsl-offsets");
|
||||||
|
}
|
||||||
|
bool usingHlslOFfsets() const { return hlslOffsets; }
|
||||||
|
void setUseStorageBuffer()
|
||||||
|
{
|
||||||
|
useStorageBuffer = true;
|
||||||
|
processes.addProcess("use-storage-buffer");
|
||||||
|
}
|
||||||
|
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||||
|
void setHlslIoMapping(bool b)
|
||||||
|
{
|
||||||
|
hlslIoMapping = b;
|
||||||
|
if (hlslIoMapping)
|
||||||
|
processes.addProcess("hlsl-iomap");
|
||||||
|
}
|
||||||
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
|
||||||
|
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
||||||
|
bool hasCounterBufferName(const TString& name) const {
|
||||||
|
size_t len = strlen(implicitCounterName);
|
||||||
|
return name.size() > len &&
|
||||||
|
name.compare(name.size() - len, len, implicitCounterName) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v) { version = v; }
|
||||||
int getVersion() const { return version; }
|
int getVersion() const { return version; }
|
||||||
void setProfile(EProfile p) { profile = p; }
|
void setProfile(EProfile p) { profile = p; }
|
||||||
EProfile getProfile() const { return profile; }
|
EProfile getProfile() const { return profile; }
|
||||||
void setSpv(const SpvVersion& s) { spvVersion = s; }
|
void setSpv(const SpvVersion& s)
|
||||||
|
{
|
||||||
|
spvVersion = s;
|
||||||
|
|
||||||
|
// client processes
|
||||||
|
if (spvVersion.vulkan > 0)
|
||||||
|
processes.addProcess("client vulkan100");
|
||||||
|
if (spvVersion.openGl > 0)
|
||||||
|
processes.addProcess("client opengl100");
|
||||||
|
|
||||||
|
// target-environment processes
|
||||||
|
if (spvVersion.vulkan > 0)
|
||||||
|
processes.addProcess("target-env vulkan1.0");
|
||||||
|
else if (spvVersion.vulkan > 0)
|
||||||
|
processes.addProcess("target-env vulkanUnknown");
|
||||||
|
if (spvVersion.openGl > 0)
|
||||||
|
processes.addProcess("target-env opengl");
|
||||||
|
}
|
||||||
const SpvVersion& getSpv() const { return spvVersion; }
|
const SpvVersion& getSpv() const { return spvVersion; }
|
||||||
EShLanguage getStage() const { return language; }
|
EShLanguage getStage() const { return language; }
|
||||||
void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); }
|
void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); }
|
||||||
|
@ -162,8 +402,8 @@ public:
|
||||||
|
|
||||||
void setTreeRoot(TIntermNode* r) { treeRoot = r; }
|
void setTreeRoot(TIntermNode* r) { treeRoot = r; }
|
||||||
TIntermNode* getTreeRoot() const { return treeRoot; }
|
TIntermNode* getTreeRoot() const { return treeRoot; }
|
||||||
void addMainCount() { ++numMains; }
|
void incrementEntryPointCount() { ++numEntryPoints; }
|
||||||
int getNumMains() const { return numMains; }
|
int getNumEntryPoints() const { return numEntryPoints; }
|
||||||
int getNumErrors() const { return numErrors; }
|
int getNumErrors() const { return numErrors; }
|
||||||
void addPushConstantCount() { ++numPushConstants; }
|
void addPushConstantCount() { ++numPushConstants; }
|
||||||
bool isRecursive() const { return recursive; }
|
bool isRecursive() const { return recursive; }
|
||||||
|
@ -171,50 +411,74 @@ public:
|
||||||
TIntermSymbol* addSymbol(const TVariable&);
|
TIntermSymbol* addSymbol(const TVariable&);
|
||||||
TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&);
|
TIntermSymbol* addSymbol(const TVariable&, const TSourceLoc&);
|
||||||
TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
|
TIntermSymbol* addSymbol(const TType&, const TSourceLoc&);
|
||||||
|
TIntermSymbol* addSymbol(const TIntermSymbol&);
|
||||||
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
|
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
|
||||||
|
std::tuple<TIntermTyped*, TIntermTyped*> addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) const;
|
||||||
|
TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
|
||||||
|
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
|
||||||
|
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
|
||||||
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||||
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
|
||||||
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
|
||||||
TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc);
|
TIntermTyped* addUnaryMath(TOperator, TIntermTyped* child, TSourceLoc);
|
||||||
TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType);
|
TIntermTyped* addBuiltInFunctionCall(const TSourceLoc& line, TOperator, bool unary, TIntermNode*, const TType& returnType);
|
||||||
bool canImplicitlyPromote(TBasicType from, TBasicType to) const;
|
bool canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op = EOpNull) const;
|
||||||
|
bool isIntegralPromotion(TBasicType from, TBasicType to) const;
|
||||||
|
bool isFPPromotion(TBasicType from, TBasicType to) const;
|
||||||
|
bool isIntegralConversion(TBasicType from, TBasicType to) const;
|
||||||
|
bool isFPConversion(TBasicType from, TBasicType to) const;
|
||||||
|
bool isFPIntegralConversion(TBasicType from, TBasicType to) const;
|
||||||
|
TOperator mapTypeToConstructorOp(const TType&) const;
|
||||||
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
|
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right);
|
||||||
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
|
TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&);
|
||||||
TIntermAggregate* makeAggregate(TIntermNode* node);
|
TIntermAggregate* makeAggregate(TIntermNode* node);
|
||||||
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
|
TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&);
|
||||||
|
TIntermAggregate* makeAggregate(const TSourceLoc&);
|
||||||
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
|
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
|
||||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||||
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
|
TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
|
||||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
|
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
|
||||||
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
|
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
|
||||||
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
|
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
|
||||||
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
|
||||||
|
TIntermConstantUnion* addConstantUnion(signed char, const TSourceLoc&, bool literal = false) const;
|
||||||
|
TIntermConstantUnion* addConstantUnion(unsigned char, const TSourceLoc&, bool literal = false) const;
|
||||||
|
TIntermConstantUnion* addConstantUnion(signed short, const TSourceLoc&, bool literal = false) const;
|
||||||
|
TIntermConstantUnion* addConstantUnion(unsigned short, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
|
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
|
||||||
|
TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
|
||||||
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
|
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
|
||||||
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
|
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
|
||||||
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
|
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
|
||||||
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
|
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst,
|
||||||
|
const TSourceLoc&, TIntermLoop*&);
|
||||||
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
|
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
|
||||||
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
|
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
|
||||||
TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
|
template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
|
||||||
|
|
||||||
|
// Low level functions to add nodes (no conversions or other higher level transformations)
|
||||||
|
// If a type is provided, the node's type will be set to it.
|
||||||
|
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc) const;
|
||||||
|
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, const TType&) const;
|
||||||
|
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const;
|
||||||
|
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const;
|
||||||
|
|
||||||
// Constant folding (in Constant.cpp)
|
// Constant folding (in Constant.cpp)
|
||||||
TIntermTyped* fold(TIntermAggregate* aggrNode);
|
TIntermTyped* fold(TIntermAggregate* aggrNode);
|
||||||
TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
|
TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
|
||||||
TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&);
|
TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&);
|
||||||
TIntermTyped* foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc&);
|
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
|
||||||
|
|
||||||
// Tree ops
|
// Tree ops
|
||||||
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
|
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
|
||||||
|
|
||||||
// Linkage related
|
// Linkage related
|
||||||
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
||||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
|
|
||||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
||||||
|
|
||||||
bool setInvocations(int i)
|
bool setInvocations(int i)
|
||||||
|
@ -296,6 +560,8 @@ public:
|
||||||
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
||||||
void setEarlyFragmentTests() { earlyFragmentTests = true; }
|
void setEarlyFragmentTests() { earlyFragmentTests = true; }
|
||||||
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
|
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
|
||||||
|
void setPostDepthCoverage() { postDepthCoverage = true; }
|
||||||
|
bool getPostDepthCoverage() const { return postDepthCoverage; }
|
||||||
bool setDepth(TLayoutDepth d)
|
bool setDepth(TLayoutDepth d)
|
||||||
{
|
{
|
||||||
if (depthLayout != EldNone)
|
if (depthLayout != EldNone)
|
||||||
|
@ -307,20 +573,25 @@ public:
|
||||||
void setDepthReplacing() { depthReplacing = true; }
|
void setDepthReplacing() { depthReplacing = true; }
|
||||||
bool isDepthReplacing() const { return depthReplacing; }
|
bool isDepthReplacing() const { return depthReplacing; }
|
||||||
|
|
||||||
|
void setHlslFunctionality1() { hlslFunctionality1 = true; }
|
||||||
|
bool getHlslFunctionality1() const { return hlslFunctionality1; }
|
||||||
|
|
||||||
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
||||||
unsigned int getBlendEquations() const { return blendEquations; }
|
unsigned int getBlendEquations() const { return blendEquations; }
|
||||||
|
|
||||||
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
||||||
void merge(TInfoSink&, TIntermediate&);
|
void merge(TInfoSink&, TIntermediate&);
|
||||||
void finalCheck(TInfoSink&);
|
void finalCheck(TInfoSink&, bool keepUncalled);
|
||||||
|
|
||||||
void addIoAccessed(const TString& name) { ioAccessed.insert(name); }
|
void addIoAccessed(const TString& name) { ioAccessed.insert(name); }
|
||||||
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
|
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
|
||||||
|
|
||||||
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
|
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
|
||||||
|
int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision);
|
||||||
int addUsedOffsets(int binding, int offset, int numOffsets);
|
int addUsedOffsets(int binding, int offset, int numOffsets);
|
||||||
bool addUsedConstantId(int id);
|
bool addUsedConstantId(int id);
|
||||||
int computeTypeLocationSize(const TType&) const;
|
static int computeTypeLocationSize(const TType&, EShLanguage);
|
||||||
|
static int computeTypeUniformLocationSize(const TType&);
|
||||||
|
|
||||||
bool setXfbBufferStride(int buffer, unsigned stride)
|
bool setXfbBufferStride(int buffer, unsigned stride)
|
||||||
{
|
{
|
||||||
|
@ -329,34 +600,88 @@ public:
|
||||||
xfbBuffers[buffer].stride = stride;
|
xfbBuffers[buffer].stride = stride;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
|
||||||
int addXfbBufferOffset(const TType&);
|
int addXfbBufferOffset(const TType&);
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
||||||
|
static int getBaseAlignmentScalar(const TType&, int& size);
|
||||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
||||||
|
static bool improperStraddle(const TType& type, int size, int offset);
|
||||||
|
bool promote(TIntermOperator*);
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
|
||||||
|
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
||||||
|
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
|
||||||
|
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* addSemanticName(const TString& name)
|
||||||
|
{
|
||||||
|
return semanticNameSet.insert(name).first->c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
|
||||||
|
const std::string& getSourceFile() const { return sourceFile; }
|
||||||
|
void addSourceText(const char* text) { sourceText = sourceText + text; }
|
||||||
|
const std::string& getSourceText() const { return sourceText; }
|
||||||
|
void addProcesses(const std::vector<std::string>& p) {
|
||||||
|
for (int i = 0; i < (int)p.size(); ++i)
|
||||||
|
processes.addProcess(p[i]);
|
||||||
|
}
|
||||||
|
void addProcess(const std::string& process) { processes.addProcess(process); }
|
||||||
|
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
|
||||||
|
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
|
||||||
|
|
||||||
|
void setNeedsLegalization() { needToLegalize = true; }
|
||||||
|
bool needsLegalization() const { return needToLegalize; }
|
||||||
|
|
||||||
|
void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
|
||||||
|
bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
|
||||||
|
|
||||||
|
const char* const implicitThisName;
|
||||||
|
const char* const implicitCounterName;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||||
void error(TInfoSink& infoSink, const char*);
|
void error(TInfoSink& infoSink, const char*);
|
||||||
|
void warn(TInfoSink& infoSink, const char*);
|
||||||
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
|
void mergeBodies(TInfoSink&, TIntermSequence& globals, const TIntermSequence& unitGlobals);
|
||||||
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
|
void mergeLinkerObjects(TInfoSink&, TIntermSequence& linkerObjects, const TIntermSequence& unitLinkerObjects);
|
||||||
void mergeImplicitArraySizes(TType&, const TType&);
|
void mergeImplicitArraySizes(TType&, const TType&);
|
||||||
void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage);
|
void mergeErrorCheck(TInfoSink&, const TIntermSymbol&, const TIntermSymbol&, bool crossStage);
|
||||||
void checkCallGraphCycles(TInfoSink&);
|
void checkCallGraphCycles(TInfoSink&);
|
||||||
|
void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
|
||||||
void inOutLocationCheck(TInfoSink&);
|
void inOutLocationCheck(TInfoSink&);
|
||||||
TIntermSequence& findLinkerObjects() const;
|
TIntermSequence& findLinkerObjects() const;
|
||||||
bool userOutputUsed() const;
|
bool userOutputUsed() const;
|
||||||
static int getBaseAlignmentScalar(const TType&, int& size);
|
|
||||||
bool isSpecializationOperation(const TIntermOperator&) const;
|
bool isSpecializationOperation(const TIntermOperator&) const;
|
||||||
|
bool isNonuniformPropagating(TOperator) const;
|
||||||
|
bool promoteUnary(TIntermUnary&);
|
||||||
|
bool promoteBinary(TIntermBinary&);
|
||||||
|
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
|
||||||
|
bool promoteAggregate(TIntermAggregate&);
|
||||||
|
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
||||||
|
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
||||||
|
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||||
|
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||||
|
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
|
||||||
|
TIntermUnary* createConversion(TBasicType convertTo, TIntermTyped* node) const;
|
||||||
|
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
|
||||||
|
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
|
||||||
|
static const char* getResourceName(TResourceType);
|
||||||
|
|
||||||
const EShLanguage language; // stage, known at construction time
|
const EShLanguage language; // stage, known at construction time
|
||||||
EShSource source; // source language, known a bit later
|
EShSource source; // source language, known a bit later
|
||||||
std::string entryPoint;
|
std::string entryPointName;
|
||||||
EProfile profile;
|
std::string entryPointMangledName;
|
||||||
int version;
|
|
||||||
|
EProfile profile; // source profile
|
||||||
|
int version; // source version
|
||||||
SpvVersion spvVersion;
|
SpvVersion spvVersion;
|
||||||
TIntermNode* treeRoot;
|
TIntermNode* treeRoot;
|
||||||
std::set<std::string> requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
|
std::set<std::string> requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
|
||||||
TBuiltInResource resources;
|
TBuiltInResource resources;
|
||||||
int numMains;
|
int numEntryPoints;
|
||||||
int numErrors;
|
int numErrors;
|
||||||
int numPushConstants;
|
int numPushConstants;
|
||||||
bool recursive;
|
bool recursive;
|
||||||
|
@ -372,12 +697,35 @@ protected:
|
||||||
int localSize[3];
|
int localSize[3];
|
||||||
int localSizeSpecId[3];
|
int localSizeSpecId[3];
|
||||||
bool earlyFragmentTests;
|
bool earlyFragmentTests;
|
||||||
|
bool postDepthCoverage;
|
||||||
TLayoutDepth depthLayout;
|
TLayoutDepth depthLayout;
|
||||||
bool depthReplacing;
|
bool depthReplacing;
|
||||||
|
bool hlslFunctionality1;
|
||||||
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
||||||
bool xfbMode;
|
bool xfbMode;
|
||||||
bool multiStream;
|
bool multiStream;
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
bool layoutOverrideCoverage;
|
||||||
|
bool geoPassthroughEXT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Base shift values
|
||||||
|
std::array<unsigned int, EResCount> shiftBinding;
|
||||||
|
|
||||||
|
// Per-descriptor-set shift values
|
||||||
|
std::array<std::map<int, int>, EResCount> shiftBindingForSet;
|
||||||
|
|
||||||
|
std::vector<std::string> resourceSetBinding;
|
||||||
|
bool autoMapBindings;
|
||||||
|
bool autoMapLocations;
|
||||||
|
bool invertY;
|
||||||
|
bool flattenUniformArrays;
|
||||||
|
bool useUnknownFormat;
|
||||||
|
bool hlslOffsets;
|
||||||
|
bool useStorageBuffer;
|
||||||
|
bool hlslIoMapping;
|
||||||
|
|
||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
TGraph callGraph;
|
TGraph callGraph;
|
||||||
|
|
||||||
|
@ -386,6 +734,19 @@ protected:
|
||||||
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
||||||
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
||||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||||
|
std::set<TString> semanticNameSet;
|
||||||
|
|
||||||
|
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
||||||
|
|
||||||
|
// source code of shader, useful as part of debug information
|
||||||
|
std::string sourceFile;
|
||||||
|
std::string sourceText;
|
||||||
|
|
||||||
|
// for OpModuleProcessed, or equivalent
|
||||||
|
TProcesses processes;
|
||||||
|
|
||||||
|
bool needToLegalize;
|
||||||
|
bool binaryDoubleOutput;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=(TIntermediate&); // prevent assignments
|
void operator=(TIntermediate&); // prevent assignments
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,22 +18,22 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
//
|
//
|
||||||
// Travarse a tree of constants to create a single folded constant.
|
// Traverse a tree of constants to create a single folded constant.
|
||||||
// It should only be used when the whole tree is known to be constant.
|
// It should only be used when the whole tree is known to be constant.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -76,12 +76,6 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->getSequence().size() == 0) {
|
|
||||||
error = true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
|
bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
|
||||||
if (flag) {
|
if (flag) {
|
||||||
singleConstantParam = true;
|
singleConstantParam = true;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2016 Google, Inc.
|
// Copyright (C) 2016 Google, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
//
|
//
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +20,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
// This is implemented in Versions.cpp
|
// This is implemented in Versions.cpp
|
||||||
|
@ -68,6 +69,7 @@ public:
|
||||||
virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
|
virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
|
||||||
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
||||||
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
||||||
|
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
|
||||||
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
||||||
virtual TExtensionBehavior getExtensionBehavior(const char*);
|
virtual TExtensionBehavior getExtensionBehavior(const char*);
|
||||||
|
@ -76,7 +78,16 @@ public:
|
||||||
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
|
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
|
||||||
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
||||||
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
||||||
|
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
#endif
|
||||||
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
|
virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void spvRemoved(const TSourceLoc&, const char* op);
|
virtual void spvRemoved(const TSourceLoc&, const char* op);
|
||||||
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
||||||
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
||||||
|
@ -107,6 +118,8 @@ public:
|
||||||
void getPreamble(std::string&);
|
void getPreamble(std::string&);
|
||||||
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
|
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
|
||||||
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
||||||
|
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
|
||||||
|
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
|
||||||
|
|
||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
|
|
||||||
|
@ -119,12 +132,12 @@ public:
|
||||||
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
||||||
EShMessages messages; // errors/warnings/rule-sets
|
EShMessages messages; // errors/warnings/rule-sets
|
||||||
int numErrors; // number of compile-time errors encountered
|
int numErrors; // number of compile-time errors encountered
|
||||||
TInputScanner* currentScanner;
|
TInputScanner* currentScanner;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TMap<TString, TExtensionBehavior> extensionBehavior; // for each extension string, what its current behavior is set to
|
|
||||||
explicit TParseVersions(const TParseVersions&);
|
explicit TParseVersions(const TParseVersions&);
|
||||||
TParseVersions& operator=(const TParseVersions&);
|
TParseVersions& operator=(const TParseVersions&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
Copyright (c) 2002, NVIDIA Corporation.
|
||||||
|
@ -75,38 +75,28 @@ NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
//
|
|
||||||
// cpp.c
|
|
||||||
//
|
|
||||||
|
|
||||||
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <ctype.h>
|
#include <cctype>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
#include "PpContext.h"
|
#include "PpContext.h"
|
||||||
#include "PpTokens.h"
|
#include "PpTokens.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
int TPpContext::InitCPP()
|
|
||||||
{
|
|
||||||
pool = mem_CreatePool(0, 0);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle #define
|
// Handle #define
|
||||||
int TPpContext::CPPdefine(TPpToken* ppToken)
|
int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
MacroSymbol mac;
|
MacroSymbol mac;
|
||||||
Symbol *symb;
|
|
||||||
|
|
||||||
// get macro name
|
// get the macro name
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
if (token != PpAtomIdentifier) {
|
if (token != PpAtomIdentifier) {
|
||||||
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
|
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#define", "");
|
||||||
|
@ -117,38 +107,36 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
|
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#define");
|
||||||
}
|
}
|
||||||
|
|
||||||
// save the original atom
|
// save the macro name
|
||||||
const int defAtom = ppToken->atom;
|
const int defAtom = atomStrings.getAddAtom(ppToken->name);
|
||||||
|
|
||||||
// gather parameters to the macro, between (...)
|
// gather parameters to the macro, between (...)
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token == '(' && ! ppToken->space) {
|
if (token == '(' && ! ppToken->space) {
|
||||||
int argc = 0;
|
mac.emptyArgs = 1;
|
||||||
int args[maxMacroArgs];
|
|
||||||
do {
|
do {
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (argc == 0 && token == ')')
|
if (mac.args.size() == 0 && token == ')')
|
||||||
break;
|
break;
|
||||||
if (token != PpAtomIdentifier) {
|
if (token != PpAtomIdentifier) {
|
||||||
parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
|
parseContext.ppError(ppToken->loc, "bad argument", "#define", "");
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
mac.emptyArgs = 0;
|
||||||
|
const int argAtom = atomStrings.getAddAtom(ppToken->name);
|
||||||
|
|
||||||
// check for duplication of parameter name
|
// check for duplication of parameter name
|
||||||
bool duplicate = false;
|
bool duplicate = false;
|
||||||
for (int a = 0; a < argc; ++a) {
|
for (size_t a = 0; a < mac.args.size(); ++a) {
|
||||||
if (args[a] == ppToken->atom) {
|
if (mac.args[a] == argAtom) {
|
||||||
parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
|
parseContext.ppError(ppToken->loc, "duplicate macro parameter", "#define", "");
|
||||||
duplicate = true;
|
duplicate = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! duplicate) {
|
if (! duplicate)
|
||||||
if (argc < maxMacroArgs)
|
mac.args.push_back(argAtom);
|
||||||
args[argc++] = ppToken->atom;
|
|
||||||
else
|
|
||||||
parseContext.ppError(ppToken->loc, "too many macro parameters", "#define", "");
|
|
||||||
}
|
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
} while (token == ',');
|
} while (token == ',');
|
||||||
if (token != ')') {
|
if (token != ')') {
|
||||||
|
@ -156,57 +144,50 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
mac.argc = argc;
|
|
||||||
mac.args = (int*)mem_Alloc(pool, argc * sizeof(int));
|
|
||||||
memcpy(mac.args, args, argc * sizeof(int));
|
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// record the definition of the macro
|
// record the definition of the macro
|
||||||
TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
|
TSourceLoc defineLoc = ppToken->loc; // because ppToken is going to go to the next line before we report errors
|
||||||
mac.body = new TokenStream;
|
|
||||||
while (token != '\n' && token != EndOfInput) {
|
while (token != '\n' && token != EndOfInput) {
|
||||||
RecordToken(mac.body, token, ppToken);
|
mac.body.putToken(token, ppToken);
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token != '\n' && ppToken->space)
|
if (token != '\n' && ppToken->space)
|
||||||
RecordToken(mac.body, ' ', ppToken);
|
mac.body.putToken(' ', ppToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for duplicate definition
|
// check for duplicate definition
|
||||||
symb = LookUpSymbol(defAtom);
|
MacroSymbol* existing = lookupMacroDef(defAtom);
|
||||||
if (symb) {
|
if (existing != nullptr) {
|
||||||
if (! symb->mac.undef) {
|
if (! existing->undef) {
|
||||||
// Already defined -- need to make sure they are identical:
|
// Already defined -- need to make sure they are identical:
|
||||||
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
|
// "Two replacement lists are identical if and only if the preprocessing tokens in both have the same number,
|
||||||
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
|
// ordering, spelling, and white-space separation, where all white-space separations are considered identical."
|
||||||
if (symb->mac.argc != mac.argc)
|
if (existing->args.size() != mac.args.size() || existing->emptyArgs != mac.emptyArgs)
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", GetAtomString(defAtom));
|
parseContext.ppError(defineLoc, "Macro redefined; different number of arguments:", "#define", atomStrings.getString(defAtom));
|
||||||
else {
|
else {
|
||||||
for (int argc = 0; argc < mac.argc; argc++) {
|
if (existing->args != mac.args)
|
||||||
if (symb->mac.args[argc] != mac.args[argc])
|
parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", atomStrings.getString(defAtom));
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different argument names:", "#define", GetAtomString(defAtom));
|
existing->body.reset();
|
||||||
}
|
mac.body.reset();
|
||||||
RewindTokenStream(symb->mac.body);
|
|
||||||
RewindTokenStream(mac.body);
|
|
||||||
int newToken;
|
int newToken;
|
||||||
do {
|
do {
|
||||||
int oldToken;
|
int oldToken;
|
||||||
TPpToken oldPpToken;
|
TPpToken oldPpToken;
|
||||||
TPpToken newPpToken;
|
TPpToken newPpToken;
|
||||||
oldToken = ReadToken(symb->mac.body, &oldPpToken);
|
oldToken = existing->body.getToken(parseContext, &oldPpToken);
|
||||||
newToken = ReadToken(mac.body, &newPpToken);
|
newToken = mac.body.getToken(parseContext, &newPpToken);
|
||||||
if (oldToken != newToken || oldPpToken != newPpToken) {
|
if (oldToken != newToken || oldPpToken != newPpToken) {
|
||||||
parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", GetAtomString(defAtom));
|
parseContext.ppError(defineLoc, "Macro redefined; different substitutions:", "#define", atomStrings.getString(defAtom));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (newToken > 0);
|
} while (newToken > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*existing = mac;
|
||||||
} else
|
} else
|
||||||
symb = AddSymbol(defAtom);
|
addMacroDef(defAtom, mac);
|
||||||
|
|
||||||
delete symb->mac.body;
|
|
||||||
symb->mac = mac;
|
|
||||||
|
|
||||||
return '\n';
|
return '\n';
|
||||||
}
|
}
|
||||||
|
@ -215,7 +196,6 @@ int TPpContext::CPPdefine(TPpToken* ppToken)
|
||||||
int TPpContext::CPPundef(TPpToken* ppToken)
|
int TPpContext::CPPundef(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
Symbol *symb;
|
|
||||||
if (token != PpAtomIdentifier) {
|
if (token != PpAtomIdentifier) {
|
||||||
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");
|
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#undef", "");
|
||||||
|
|
||||||
|
@ -224,10 +204,9 @@ int TPpContext::CPPundef(TPpToken* ppToken)
|
||||||
|
|
||||||
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");
|
parseContext.reservedPpErrorCheck(ppToken->loc, ppToken->name, "#undef");
|
||||||
|
|
||||||
symb = LookUpSymbol(ppToken->atom);
|
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
|
||||||
if (symb) {
|
if (macro != nullptr)
|
||||||
symb->mac.undef = 1;
|
macro->undef = 1;
|
||||||
}
|
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token != '\n')
|
if (token != '\n')
|
||||||
parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
|
parseContext.ppError(ppToken->loc, "can only be followed by a single macro name", "#undef", "");
|
||||||
|
@ -242,7 +221,6 @@ int TPpContext::CPPundef(TPpToken* ppToken)
|
||||||
*/
|
*/
|
||||||
int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int atom;
|
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
|
||||||
|
@ -261,35 +239,40 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||||
if ((token = scanToken(ppToken)) != PpAtomIdentifier)
|
if ((token = scanToken(ppToken)) != PpAtomIdentifier)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
atom = ppToken->atom;
|
int nextAtom = atomStrings.getAtom(ppToken->name);
|
||||||
if (atom == PpAtomIf || atom == PpAtomIfdef || atom == PpAtomIfndef) {
|
if (nextAtom == PpAtomIf || nextAtom == PpAtomIfdef || nextAtom == PpAtomIfndef) {
|
||||||
depth++;
|
depth++;
|
||||||
|
if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
|
||||||
|
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if/#ifdef/#ifndef", "");
|
||||||
|
return EndOfInput;
|
||||||
|
} else {
|
||||||
ifdepth++;
|
ifdepth++;
|
||||||
elsetracker++;
|
elsetracker++;
|
||||||
} else if (atom == PpAtomEndif) {
|
}
|
||||||
token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
|
} else if (nextAtom == PpAtomEndif) {
|
||||||
|
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
|
||||||
elseSeen[elsetracker] = false;
|
elseSeen[elsetracker] = false;
|
||||||
--elsetracker;
|
--elsetracker;
|
||||||
if (depth == 0) {
|
if (depth == 0) {
|
||||||
// found the #endif we are looking for
|
// found the #endif we are looking for
|
||||||
if (ifdepth)
|
if (ifdepth > 0)
|
||||||
--ifdepth;
|
--ifdepth;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
--depth;
|
--depth;
|
||||||
--ifdepth;
|
--ifdepth;
|
||||||
} else if (matchelse && depth == 0) {
|
} else if (matchelse && depth == 0) {
|
||||||
if (atom == PpAtomElse) {
|
if (nextAtom == PpAtomElse) {
|
||||||
elseSeen[elsetracker] = true;
|
elseSeen[elsetracker] = true;
|
||||||
token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
|
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
|
||||||
// found the #else we are looking for
|
// found the #else we are looking for
|
||||||
break;
|
break;
|
||||||
} else if (atom == PpAtomElif) {
|
} else if (nextAtom == PpAtomElif) {
|
||||||
if (elseSeen[elsetracker])
|
if (elseSeen[elsetracker])
|
||||||
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
||||||
/* we decrement ifdepth here, because CPPif will increment
|
/* we decrement ifdepth here, because CPPif will increment
|
||||||
* it and we really want to leave it alone */
|
* it and we really want to leave it alone */
|
||||||
if (ifdepth) {
|
if (ifdepth > 0) {
|
||||||
--ifdepth;
|
--ifdepth;
|
||||||
elseSeen[elsetracker] = false;
|
elseSeen[elsetracker] = false;
|
||||||
--elsetracker;
|
--elsetracker;
|
||||||
|
@ -297,13 +280,13 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||||
|
|
||||||
return CPPif(ppToken);
|
return CPPif(ppToken);
|
||||||
}
|
}
|
||||||
} else if (atom == PpAtomElse) {
|
} else if (nextAtom == PpAtomElse) {
|
||||||
if (elseSeen[elsetracker])
|
if (elseSeen[elsetracker])
|
||||||
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
|
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
|
||||||
else
|
else
|
||||||
elseSeen[elsetracker] = true;
|
elseSeen[elsetracker] = true;
|
||||||
token = extraTokenCheck(atom, ppToken, scanToken(ppToken));
|
token = extraTokenCheck(nextAtom, ppToken, scanToken(ppToken));
|
||||||
} else if (atom == PpAtomElif) {
|
} else if (nextAtom == PpAtomElif) {
|
||||||
if (elseSeen[elsetracker])
|
if (elseSeen[elsetracker])
|
||||||
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
||||||
}
|
}
|
||||||
|
@ -313,21 +296,21 @@ int TPpContext::CPPelse(int matchelse, TPpToken* ppToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call when there should be no more tokens left on a line.
|
// Call when there should be no more tokens left on a line.
|
||||||
int TPpContext::extraTokenCheck(int atom, TPpToken* ppToken, int token)
|
int TPpContext::extraTokenCheck(int contextAtom, TPpToken* ppToken, int token)
|
||||||
{
|
{
|
||||||
if (token != '\n' && token != EndOfInput) {
|
if (token != '\n' && token != EndOfInput) {
|
||||||
static const char* message = "unexpected tokens following directive";
|
static const char* message = "unexpected tokens following directive";
|
||||||
|
|
||||||
const char* label;
|
const char* label;
|
||||||
if (atom == PpAtomElse)
|
if (contextAtom == PpAtomElse)
|
||||||
label = "#else";
|
label = "#else";
|
||||||
else if (atom == PpAtomElif)
|
else if (contextAtom == PpAtomElif)
|
||||||
label = "#elif";
|
label = "#elif";
|
||||||
else if (atom == PpAtomEndif)
|
else if (contextAtom == PpAtomEndif)
|
||||||
label = "#endif";
|
label = "#endif";
|
||||||
else if (atom == PpAtomIf)
|
else if (contextAtom == PpAtomIf)
|
||||||
label = "#if";
|
label = "#if";
|
||||||
else if (atom == PpAtomLine)
|
else if (contextAtom == PpAtomLine)
|
||||||
label = "#line";
|
label = "#line";
|
||||||
else
|
else
|
||||||
label = "";
|
label = "";
|
||||||
|
@ -368,8 +351,8 @@ namespace {
|
||||||
int op_add(int a, int b) { return a + b; }
|
int op_add(int a, int b) { return a + b; }
|
||||||
int op_sub(int a, int b) { return a - b; }
|
int op_sub(int a, int b) { return a - b; }
|
||||||
int op_mul(int a, int b) { return a * b; }
|
int op_mul(int a, int b) { return a * b; }
|
||||||
int op_div(int a, int b) { return a / b; }
|
int op_div(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a / b; }
|
||||||
int op_mod(int a, int b) { return a % b; }
|
int op_mod(int a, int b) { return a == INT_MIN && b == -1 ? 0 : a % b; }
|
||||||
int op_pos(int a) { return a; }
|
int op_pos(int a) { return a; }
|
||||||
int op_neg(int a) { return -a; }
|
int op_neg(int a) { return -a; }
|
||||||
int op_cmpl(int a) { return ~a; }
|
int op_cmpl(int a) { return ~a; }
|
||||||
|
@ -415,7 +398,15 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
|
||||||
{
|
{
|
||||||
TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error
|
TSourceLoc loc = ppToken->loc; // because we sometimes read the newline before reporting the error
|
||||||
if (token == PpAtomIdentifier) {
|
if (token == PpAtomIdentifier) {
|
||||||
if (ppToken->atom == PpAtomDefined) {
|
if (strcmp("defined", ppToken->name) == 0) {
|
||||||
|
if (! parseContext.isReadingHLSL() && isMacroInput()) {
|
||||||
|
if (parseContext.relaxedErrors())
|
||||||
|
parseContext.ppWarn(ppToken->loc, "nonportable when expanded from macros for preprocessor expression",
|
||||||
|
"defined", "");
|
||||||
|
else
|
||||||
|
parseContext.ppError(ppToken->loc, "cannot use in preprocessor expression when expanded from macros",
|
||||||
|
"defined", "");
|
||||||
|
}
|
||||||
bool needclose = 0;
|
bool needclose = 0;
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token == '(') {
|
if (token == '(') {
|
||||||
|
@ -429,8 +420,9 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
Symbol* s = LookUpSymbol(ppToken->atom);
|
|
||||||
res = s ? ! s->mac.undef : 0;
|
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
|
||||||
|
res = macro != nullptr ? !macro->undef : 0;
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (needclose) {
|
if (needclose) {
|
||||||
if (token != ')') {
|
if (token != ')') {
|
||||||
|
@ -522,8 +514,8 @@ int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, boo
|
||||||
// Expand macros, skipping empty expansions, to get to the first real token in those expansions.
|
// Expand macros, skipping empty expansions, to get to the first real token in those expansions.
|
||||||
int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
|
int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
while (token == PpAtomIdentifier && ppToken->atom != PpAtomDefined) {
|
while (token == PpAtomIdentifier && strcmp("defined", ppToken->name) != 0) {
|
||||||
int macroReturn = MacroExpand(ppToken->atom, ppToken, true, false);
|
int macroReturn = MacroExpand(ppToken, true, false);
|
||||||
if (macroReturn == 0) {
|
if (macroReturn == 0) {
|
||||||
parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
|
parseContext.ppError(ppToken->loc, "can't evaluate expression", "preprocessor evaluation", "");
|
||||||
err = true;
|
err = true;
|
||||||
|
@ -550,11 +542,12 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T
|
||||||
int TPpContext::CPPif(TPpToken* ppToken)
|
int TPpContext::CPPif(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
if (ifdepth >= maxIfNesting || elsetracker >= maxIfNesting) {
|
||||||
|
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
|
||||||
|
return EndOfInput;
|
||||||
|
} else {
|
||||||
elsetracker++;
|
elsetracker++;
|
||||||
ifdepth++;
|
ifdepth++;
|
||||||
if (ifdepth > maxIfNesting) {
|
|
||||||
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#if", "");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
int res = 0;
|
int res = 0;
|
||||||
bool err = false;
|
bool err = false;
|
||||||
|
@ -570,72 +563,105 @@ int TPpContext::CPPif(TPpToken* ppToken)
|
||||||
int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
|
int TPpContext::CPPifdef(int defined, TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
int name = ppToken->atom;
|
if (ifdepth > maxIfNesting || elsetracker > maxIfNesting) {
|
||||||
if (++ifdepth > maxIfNesting) {
|
|
||||||
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
|
parseContext.ppError(ppToken->loc, "maximum nesting depth exceeded", "#ifdef", "");
|
||||||
return 0;
|
return EndOfInput;
|
||||||
}
|
} else {
|
||||||
elsetracker++;
|
elsetracker++;
|
||||||
|
ifdepth++;
|
||||||
|
}
|
||||||
|
|
||||||
if (token != PpAtomIdentifier) {
|
if (token != PpAtomIdentifier) {
|
||||||
if (defined)
|
if (defined)
|
||||||
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
|
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifdef", "");
|
||||||
else
|
else
|
||||||
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
|
parseContext.ppError(ppToken->loc, "must be followed by macro name", "#ifndef", "");
|
||||||
} else {
|
} else {
|
||||||
Symbol *s = LookUpSymbol(name);
|
MacroSymbol* macro = lookupMacroDef(atomStrings.getAtom(ppToken->name));
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token != '\n') {
|
if (token != '\n') {
|
||||||
parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
|
parseContext.ppError(ppToken->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
|
||||||
while (token != '\n' && token != EndOfInput)
|
while (token != '\n' && token != EndOfInput)
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
}
|
}
|
||||||
if (((s && !s->mac.undef) ? 1 : 0) != defined)
|
if (((macro != nullptr && !macro->undef) ? 1 : 0) != defined)
|
||||||
token = CPPelse(1, ppToken);
|
token = CPPelse(1, ppToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle #include
|
// Handle #include ...
|
||||||
|
// TODO: Handle macro expansions for the header name
|
||||||
int TPpContext::CPPinclude(TPpToken* ppToken)
|
int TPpContext::CPPinclude(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
const TSourceLoc directiveLoc = ppToken->loc;
|
const TSourceLoc directiveLoc = ppToken->loc;
|
||||||
|
bool startWithLocalSearch = true; // to additionally include the extra "" paths
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
|
||||||
|
// handle <header-name>-style #include
|
||||||
|
if (token == '<') {
|
||||||
|
startWithLocalSearch = false;
|
||||||
|
token = scanHeaderName(ppToken, '>');
|
||||||
|
}
|
||||||
|
// otherwise ppToken already has the header name and it was "header-name" style
|
||||||
|
|
||||||
if (token != PpAtomConstString) {
|
if (token != PpAtomConstString) {
|
||||||
// TODO: handle angle brackets.
|
parseContext.ppError(directiveLoc, "must be followed by a header name", "#include", "");
|
||||||
parseContext.ppError(directiveLoc, "must be followed by a file designation", "#include", "");
|
return token;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
// Make a copy of the name because it will be overwritten by the next token scan.
|
// Make a copy of the name because it will be overwritten by the next token scan.
|
||||||
const std::string filename = ppToken->name;
|
const std::string filename = ppToken->name;
|
||||||
|
|
||||||
|
// See if the directive was well formed
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token != '\n' && token != EndOfInput) {
|
if (token != '\n') {
|
||||||
parseContext.ppError(ppToken->loc, "extra content after file designation", "#include", "");
|
if (token == EndOfInput)
|
||||||
} else {
|
parseContext.ppError(ppToken->loc, "expected newline after header name:", "#include", "%s", filename.c_str());
|
||||||
TShader::Includer::IncludeResult* res = includer.include(filename.c_str(), TShader::Includer::EIncludeRelative, currentSourceFile.c_str(), includeStack.size() + 1);
|
else
|
||||||
if (res && !res->file_name.empty()) {
|
parseContext.ppError(ppToken->loc, "extra content after header name:", "#include", "%s", filename.c_str());
|
||||||
if (res->file_data && res->file_length) {
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process well-formed directive
|
||||||
|
|
||||||
|
// Find the inclusion, first look in "Local" ("") paths, if requested,
|
||||||
|
// otherwise, only search the "System" (<>) paths.
|
||||||
|
TShader::Includer::IncludeResult* res = nullptr;
|
||||||
|
if (startWithLocalSearch)
|
||||||
|
res = includer.includeLocal(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
||||||
|
if (res == nullptr || res->headerName.empty()) {
|
||||||
|
includer.releaseInclude(res);
|
||||||
|
res = includer.includeSystem(filename.c_str(), currentSourceFile.c_str(), includeStack.size() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the results
|
||||||
|
if (res != nullptr && !res->headerName.empty()) {
|
||||||
|
if (res->headerData != nullptr && res->headerLength > 0) {
|
||||||
|
// path for processing one or more tokens from an included header, hand off 'res'
|
||||||
const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
|
const bool forNextLine = parseContext.lineDirectiveShouldSetNextLine();
|
||||||
std::ostringstream prologue;
|
std::ostringstream prologue;
|
||||||
std::ostringstream epilogue;
|
std::ostringstream epilogue;
|
||||||
prologue << "#line " << forNextLine << " " << "\"" << res->file_name << "\"\n";
|
prologue << "#line " << forNextLine << " " << "\"" << res->headerName << "\"\n";
|
||||||
epilogue << (res->file_data[res->file_length - 1] == '\n'? "" : "\n") << "#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
|
epilogue << (res->headerData[res->headerLength - 1] == '\n'? "" : "\n") <<
|
||||||
|
"#line " << directiveLoc.line + forNextLine << " " << directiveLoc.getStringNameOrNum() << "\n";
|
||||||
pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
|
pushInput(new TokenizableIncludeFile(directiveLoc, prologue.str(), res, epilogue.str(), this));
|
||||||
}
|
// There's no "current" location anymore.
|
||||||
// At EOF, there's no "current" location anymore.
|
parseContext.setCurrentColumn(0);
|
||||||
if (token != EndOfInput) parseContext.setCurrentColumn(0);
|
|
||||||
// Don't accidentally return EndOfInput, which will end all preprocessing.
|
|
||||||
return '\n';
|
|
||||||
} else {
|
} else {
|
||||||
std::string message =
|
// things are okay, but there is nothing to process
|
||||||
res ? std::string(res->file_data, res->file_length)
|
|
||||||
: std::string("Could not process include directive");
|
|
||||||
parseContext.ppError(directiveLoc, message.c_str(), "#include", "");
|
|
||||||
if (res) {
|
|
||||||
includer.releaseInclude(res);
|
includer.releaseInclude(res);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// error path, clean up
|
||||||
|
std::string message =
|
||||||
|
res != nullptr ? std::string(res->headerData, res->headerLength)
|
||||||
|
: std::string("Could not process include directive");
|
||||||
|
parseContext.ppError(directiveLoc, message.c_str(), "#include", "for header name: %s", filename.c_str());
|
||||||
|
includer.releaseInclude(res);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +702,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
||||||
// We need to save a copy of the string instead of pointing
|
// We need to save a copy of the string instead of pointing
|
||||||
// to the name field of the token since the name field
|
// to the name field of the token since the name field
|
||||||
// will likely be overwritten by the next token scan.
|
// will likely be overwritten by the next token scan.
|
||||||
sourceName = GetAtomString(LookUpAddString(ppToken->name));
|
sourceName = atomStrings.getString(atomStrings.getAddAtom(ppToken->name));
|
||||||
parseContext.setCurrentSourceName(sourceName);
|
parseContext.setCurrentSourceName(sourceName);
|
||||||
hasFile = true;
|
hasFile = true;
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
|
@ -705,20 +731,22 @@ int TPpContext::CPPerror(TPpToken* ppToken)
|
||||||
TSourceLoc loc = ppToken->loc;
|
TSourceLoc loc = ppToken->loc;
|
||||||
|
|
||||||
while (token != '\n' && token != EndOfInput) {
|
while (token != '\n' && token != EndOfInput) {
|
||||||
if (token == PpAtomConstInt || token == PpAtomConstUint ||
|
if (token == PpAtomConstInt16 || token == PpAtomConstUint16 ||
|
||||||
|
token == PpAtomConstInt || token == PpAtomConstUint ||
|
||||||
token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
|
token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
|
||||||
|
token == PpAtomConstFloat16 ||
|
||||||
token == PpAtomConstFloat || token == PpAtomConstDouble) {
|
token == PpAtomConstFloat || token == PpAtomConstDouble) {
|
||||||
message.append(ppToken->name);
|
message.append(ppToken->name);
|
||||||
} else if (token == PpAtomIdentifier || token == PpAtomConstString) {
|
} else if (token == PpAtomIdentifier || token == PpAtomConstString) {
|
||||||
message.append(ppToken->name);
|
message.append(ppToken->name);
|
||||||
} else {
|
} else {
|
||||||
message.append(GetAtomString(token));
|
message.append(atomStrings.getString(token));
|
||||||
}
|
}
|
||||||
message.append(" ");
|
message.append(" ");
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
}
|
}
|
||||||
parseContext.notifyErrorDirective(loc.line, message.c_str());
|
parseContext.notifyErrorDirective(loc.line, message.c_str());
|
||||||
//store this msg into the shader's information log..set the Compile Error flag!!!!
|
// store this msg into the shader's information log..set the Compile Error flag!!!!
|
||||||
parseContext.ppError(loc, message.c_str(), "#error", "");
|
parseContext.ppError(loc, message.c_str(), "#error", "");
|
||||||
|
|
||||||
return '\n';
|
return '\n';
|
||||||
|
@ -739,8 +767,13 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
|
||||||
case PpAtomConstUint:
|
case PpAtomConstUint:
|
||||||
case PpAtomConstInt64:
|
case PpAtomConstInt64:
|
||||||
case PpAtomConstUint64:
|
case PpAtomConstUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
case PpAtomConstFloat:
|
case PpAtomConstFloat:
|
||||||
case PpAtomConstDouble:
|
case PpAtomConstDouble:
|
||||||
|
case PpAtomConstFloat16:
|
||||||
tokens.push_back(ppToken->name);
|
tokens.push_back(ppToken->name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -764,8 +797,12 @@ int TPpContext::CPPversion(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
|
||||||
if (errorOnVersion || versionSeen)
|
if (errorOnVersion || versionSeen) {
|
||||||
|
if (parseContext.isReadingHLSL())
|
||||||
|
parseContext.ppError(ppToken->loc, "invalid preprocessor command", "#version", "");
|
||||||
|
else
|
||||||
parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
|
parseContext.ppError(ppToken->loc, "must occur first in shader", "#version", "");
|
||||||
|
}
|
||||||
versionSeen = true;
|
versionSeen = true;
|
||||||
|
|
||||||
if (token == '\n') {
|
if (token == '\n') {
|
||||||
|
@ -786,9 +823,10 @@ int TPpContext::CPPversion(TPpToken* ppToken)
|
||||||
parseContext.notifyVersion(line, versionNumber, nullptr);
|
parseContext.notifyVersion(line, versionNumber, nullptr);
|
||||||
return token;
|
return token;
|
||||||
} else {
|
} else {
|
||||||
if (ppToken->atom != PpAtomCore &&
|
int profileAtom = atomStrings.getAtom(ppToken->name);
|
||||||
ppToken->atom != PpAtomCompatibility &&
|
if (profileAtom != PpAtomCore &&
|
||||||
ppToken->atom != PpAtomEs)
|
profileAtom != PpAtomCompatibility &&
|
||||||
|
profileAtom != PpAtomEs)
|
||||||
parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
|
parseContext.ppError(ppToken->loc, "bad profile name; use es, core, or compatibility", "#version", "");
|
||||||
parseContext.notifyVersion(line, versionNumber, ppToken->name);
|
parseContext.notifyVersion(line, versionNumber, ppToken->name);
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
|
@ -849,21 +887,21 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||||
int token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
|
|
||||||
if (token == PpAtomIdentifier) {
|
if (token == PpAtomIdentifier) {
|
||||||
switch (ppToken->atom) {
|
switch (atomStrings.getAtom(ppToken->name)) {
|
||||||
case PpAtomDefine:
|
case PpAtomDefine:
|
||||||
token = CPPdefine(ppToken);
|
token = CPPdefine(ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomElse:
|
case PpAtomElse:
|
||||||
if (elsetracker[elseSeen])
|
if (elseSeen[elsetracker])
|
||||||
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
|
parseContext.ppError(ppToken->loc, "#else after #else", "#else", "");
|
||||||
elsetracker[elseSeen] = true;
|
elseSeen[elsetracker] = true;
|
||||||
if (! ifdepth)
|
if (ifdepth == 0)
|
||||||
parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
|
parseContext.ppError(ppToken->loc, "mismatched statements", "#else", "");
|
||||||
token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken));
|
token = extraTokenCheck(PpAtomElse, ppToken, scanToken(ppToken));
|
||||||
token = CPPelse(0, ppToken);
|
token = CPPelse(0, ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomElif:
|
case PpAtomElif:
|
||||||
if (! ifdepth)
|
if (ifdepth == 0)
|
||||||
parseContext.ppError(ppToken->loc, "mismatched statements", "#elif", "");
|
parseContext.ppError(ppToken->loc, "mismatched statements", "#elif", "");
|
||||||
if (elseSeen[elsetracker])
|
if (elseSeen[elsetracker])
|
||||||
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
parseContext.ppError(ppToken->loc, "#elif after #else", "#elif", "");
|
||||||
|
@ -874,7 +912,7 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||||
token = CPPelse(0, ppToken);
|
token = CPPelse(0, ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomEndif:
|
case PpAtomEndif:
|
||||||
if (! ifdepth)
|
if (ifdepth == 0)
|
||||||
parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
|
parseContext.ppError(ppToken->loc, "mismatched statements", "#endif", "");
|
||||||
else {
|
else {
|
||||||
elseSeen[elsetracker] = false;
|
elseSeen[elsetracker] = false;
|
||||||
|
@ -893,7 +931,9 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||||
token = CPPifdef(0, ppToken);
|
token = CPPifdef(0, ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomInclude:
|
case PpAtomInclude:
|
||||||
|
if(!parseContext.isReadingHLSL()) {
|
||||||
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
|
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
|
||||||
|
}
|
||||||
token = CPPinclude(ppToken);
|
token = CPPinclude(ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomLine:
|
case PpAtomLine:
|
||||||
|
@ -927,52 +967,128 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream* a, TPpToken* ppToken, bool newLineOkay)
|
// Context-dependent parsing of a #include <header-name>.
|
||||||
|
// Assumes no macro expansions etc. are being done; the name is just on the current input.
|
||||||
|
// Always creates a name and returns PpAtomicConstString, unless we run out of input.
|
||||||
|
int TPpContext::scanHeaderName(TPpToken* ppToken, char delimit)
|
||||||
{
|
{
|
||||||
int token;
|
bool tooLong = false;
|
||||||
TokenStream *n;
|
|
||||||
RewindTokenStream(a);
|
if (inputStack.empty())
|
||||||
|
return EndOfInput;
|
||||||
|
|
||||||
|
int len = 0;
|
||||||
|
ppToken->name[0] = '\0';
|
||||||
do {
|
do {
|
||||||
token = ReadToken(a, ppToken);
|
int ch = inputStack.back()->getch();
|
||||||
if (token == PpAtomIdentifier && LookUpSymbol(ppToken->atom))
|
|
||||||
break;
|
|
||||||
} while (token != EndOfInput);
|
|
||||||
|
|
||||||
if (token == EndOfInput)
|
// done yet?
|
||||||
return a;
|
if (ch == delimit) {
|
||||||
|
ppToken->name[len] = '\0';
|
||||||
|
if (tooLong)
|
||||||
|
parseContext.ppError(ppToken->loc, "header name too long", "", "");
|
||||||
|
return PpAtomConstString;
|
||||||
|
} else if (ch == EndOfInput)
|
||||||
|
return EndOfInput;
|
||||||
|
|
||||||
n = new TokenStream;
|
// found a character to expand the name with
|
||||||
|
if (len < MaxTokenLength)
|
||||||
|
ppToken->name[len++] = (char)ch;
|
||||||
|
else
|
||||||
|
tooLong = true;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Macro-expand a macro argument 'arg' to create 'expandedArg'.
|
||||||
|
// Does not replace 'arg'.
|
||||||
|
// Returns nullptr if no expanded argument is created.
|
||||||
|
TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream& arg, TPpToken* ppToken, bool newLineOkay)
|
||||||
|
{
|
||||||
|
// expand the argument
|
||||||
|
TokenStream* expandedArg = new TokenStream;
|
||||||
pushInput(new tMarkerInput(this));
|
pushInput(new tMarkerInput(this));
|
||||||
pushTokenStreamInput(a);
|
pushTokenStreamInput(arg);
|
||||||
while ((token = scanToken(ppToken)) != tMarkerInput::marker) {
|
int token;
|
||||||
if (token == PpAtomIdentifier && MacroExpand(ppToken->atom, ppToken, false, newLineOkay) != 0)
|
while ((token = scanToken(ppToken)) != tMarkerInput::marker && token != EndOfInput) {
|
||||||
|
token = tokenPaste(token, *ppToken);
|
||||||
|
if (token == tMarkerInput::marker || token == EndOfInput)
|
||||||
|
break;
|
||||||
|
if (token == PpAtomIdentifier && MacroExpand(ppToken, false, newLineOkay) != 0)
|
||||||
continue;
|
continue;
|
||||||
RecordToken(n, token, ppToken);
|
expandedArg->putToken(token, ppToken);
|
||||||
}
|
}
|
||||||
popInput();
|
|
||||||
delete a;
|
|
||||||
|
|
||||||
return n;
|
if (token == EndOfInput) {
|
||||||
|
// MacroExpand ate the marker, so had bad input, recover
|
||||||
|
delete expandedArg;
|
||||||
|
expandedArg = nullptr;
|
||||||
|
} else {
|
||||||
|
// remove the marker
|
||||||
|
popInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
return expandedArg;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return the next token for a macro expansion, handling macro args.
|
// Return the next token for a macro expansion, handling macro arguments,
|
||||||
|
// whose semantics are dependent on being adjacent to ##.
|
||||||
//
|
//
|
||||||
int TPpContext::tMacroInput::scan(TPpToken* ppToken)
|
int TPpContext::tMacroInput::scan(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
int token;
|
int token;
|
||||||
do {
|
do {
|
||||||
token = pp->ReadToken(mac->body, ppToken);
|
token = mac->body.getToken(pp->parseContext, ppToken);
|
||||||
} while (token == ' '); // handle white space in macro
|
} while (token == ' '); // handle white space in macro
|
||||||
|
|
||||||
|
// Hash operators basically turn off a round of macro substitution
|
||||||
|
// (the round done on the argument before the round done on the RHS of the
|
||||||
|
// macro definition):
|
||||||
|
//
|
||||||
|
// "A parameter in the replacement list, unless preceded by a # or ##
|
||||||
|
// preprocessing token or followed by a ## preprocessing token (see below),
|
||||||
|
// is replaced by the corresponding argument after all macros contained
|
||||||
|
// therein have been expanded."
|
||||||
|
//
|
||||||
|
// "If, in the replacement list, a parameter is immediately preceded or
|
||||||
|
// followed by a ## preprocessing token, the parameter is replaced by the
|
||||||
|
// corresponding argument's preprocessing token sequence."
|
||||||
|
|
||||||
|
bool pasting = false;
|
||||||
|
if (postpaste) {
|
||||||
|
// don't expand next token
|
||||||
|
pasting = true;
|
||||||
|
postpaste = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prepaste) {
|
||||||
|
// already know we should be on a ##, verify
|
||||||
|
assert(token == PpAtomPaste);
|
||||||
|
prepaste = false;
|
||||||
|
postpaste = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if are preceding a ##
|
||||||
|
if (mac->body.peekUntokenizedPasting()) {
|
||||||
|
prepaste = true;
|
||||||
|
pasting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HLSL does expand macros before concatenation
|
||||||
|
if (pasting && pp->parseContext.isReadingHLSL())
|
||||||
|
pasting = false;
|
||||||
|
|
||||||
// TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding
|
// TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding
|
||||||
if (token == PpAtomIdentifier) {
|
if (token == PpAtomIdentifier) {
|
||||||
int i;
|
int i;
|
||||||
for (i = mac->argc - 1; i >= 0; i--)
|
for (i = (int)mac->args.size() - 1; i >= 0; i--)
|
||||||
if (mac->args[i] == ppToken->atom)
|
if (strcmp(pp->atomStrings.getString(mac->args[i]), ppToken->name) == 0)
|
||||||
break;
|
break;
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
pp->pushTokenStreamInput(args[i]);
|
TokenStream* arg = expandedArgs[i];
|
||||||
|
if (arg == nullptr || pasting)
|
||||||
|
arg = args[i];
|
||||||
|
pp->pushTokenStreamInput(*arg, prepaste);
|
||||||
|
|
||||||
return pp->scanToken(ppToken);
|
return pp->scanToken(ppToken);
|
||||||
}
|
}
|
||||||
|
@ -999,17 +1115,18 @@ int TPpContext::tZeroInput::scan(TPpToken* ppToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check an identifier (atom) to see if it is a macro that should be expanded.
|
// Check a token to see if it is a macro that should be expanded.
|
||||||
// If it is, and defined, push a tInput that will produce the appropriate expansion
|
// If it is, and defined, push a tInput that will produce the appropriate expansion
|
||||||
// and return 1.
|
// and return 1.
|
||||||
// If it is, but undefined, and expandUndef is requested, push a tInput that will
|
// If it is, but undefined, and expandUndef is requested, push a tInput that will
|
||||||
// expand to 0 and return -1.
|
// expand to 0 and return -1.
|
||||||
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
|
// Otherwise, return 0 to indicate no expansion, which is not necessarily an error.
|
||||||
//
|
//
|
||||||
int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay)
|
int TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay)
|
||||||
{
|
{
|
||||||
ppToken->space = false;
|
ppToken->space = false;
|
||||||
switch (atom) {
|
int macroAtom = atomStrings.getAtom(ppToken->name);
|
||||||
|
switch (macroAtom) {
|
||||||
case PpAtomLineMacro:
|
case PpAtomLineMacro:
|
||||||
ppToken->ival = parseContext.getCurrentLoc().line;
|
ppToken->ival = parseContext.getCurrentLoc().line;
|
||||||
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
|
snprintf(ppToken->name, sizeof(ppToken->name), "%d", ppToken->ival);
|
||||||
|
@ -1035,20 +1152,19 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol *sym = LookUpSymbol(atom);
|
MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom);
|
||||||
int token;
|
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
|
|
||||||
// no recursive expansions
|
// no recursive expansions
|
||||||
if (sym && sym->mac.busy)
|
if (macro != nullptr && macro->busy)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// not expanding undefined macros
|
// not expanding undefined macros
|
||||||
if ((! sym || sym->mac.undef) && ! expandUndef)
|
if ((macro == nullptr || macro->undef) && ! expandUndef)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// 0 is the value of an undefined macro
|
// 0 is the value of an undefined macro
|
||||||
if ((! sym || sym->mac.undef) && expandUndef) {
|
if ((macro == nullptr || macro->undef) && expandUndef) {
|
||||||
pushInput(new tZeroInput(this));
|
pushInput(new tZeroInput(this));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1056,49 +1172,49 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
|
||||||
tMacroInput *in = new tMacroInput(this);
|
tMacroInput *in = new tMacroInput(this);
|
||||||
|
|
||||||
TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
|
TSourceLoc loc = ppToken->loc; // in case we go to the next line before discovering the error
|
||||||
in->mac = &sym->mac;
|
in->mac = macro;
|
||||||
if (sym->mac.args) {
|
if (macro->args.size() > 0 || macro->emptyArgs) {
|
||||||
token = scanToken(ppToken);
|
int token = scanToken(ppToken);
|
||||||
if (newLineOkay) {
|
if (newLineOkay) {
|
||||||
while (token == '\n')
|
while (token == '\n')
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
}
|
}
|
||||||
if (token != '(') {
|
if (token != '(') {
|
||||||
parseContext.ppError(loc, "expected '(' following", "macro expansion", GetAtomString(atom));
|
|
||||||
UngetToken(token, ppToken);
|
UngetToken(token, ppToken);
|
||||||
ppToken->atom = atom;
|
|
||||||
|
|
||||||
delete in;
|
delete in;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
in->args.resize(in->mac->argc);
|
in->args.resize(in->mac->args.size());
|
||||||
for (int i = 0; i < in->mac->argc; i++)
|
for (size_t i = 0; i < in->mac->args.size(); i++)
|
||||||
in->args[i] = new TokenStream;
|
in->args[i] = new TokenStream;
|
||||||
int arg = 0;
|
in->expandedArgs.resize(in->mac->args.size());
|
||||||
|
for (size_t i = 0; i < in->mac->args.size(); i++)
|
||||||
|
in->expandedArgs[i] = nullptr;
|
||||||
|
size_t arg = 0;
|
||||||
bool tokenRecorded = false;
|
bool tokenRecorded = false;
|
||||||
do {
|
do {
|
||||||
depth = 0;
|
depth = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
if (token == EndOfInput) {
|
if (token == EndOfInput || token == tMarkerInput::marker) {
|
||||||
parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
|
parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
|
||||||
delete in;
|
delete in;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (token == '\n') {
|
if (token == '\n') {
|
||||||
if (! newLineOkay) {
|
if (! newLineOkay) {
|
||||||
parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", GetAtomString(atom));
|
parseContext.ppError(loc, "End of line in macro substitution:", "macro expansion", atomStrings.getString(macroAtom));
|
||||||
delete in;
|
delete in;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (token == '#') {
|
if (token == '#') {
|
||||||
parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", GetAtomString(atom));
|
parseContext.ppError(ppToken->loc, "unexpected '#'", "macro expansion", atomStrings.getString(macroAtom));
|
||||||
delete in;
|
delete in;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (in->mac->argc == 0 && token != ')')
|
if (in->mac->args.size() == 0 && token != ')')
|
||||||
break;
|
break;
|
||||||
if (depth == 0 && (token == ',' || token == ')'))
|
if (depth == 0 && (token == ',' || token == ')'))
|
||||||
break;
|
break;
|
||||||
|
@ -1106,20 +1222,20 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
|
||||||
depth++;
|
depth++;
|
||||||
if (token == ')')
|
if (token == ')')
|
||||||
depth--;
|
depth--;
|
||||||
RecordToken(in->args[arg], token, ppToken);
|
in->args[arg]->putToken(token, ppToken);
|
||||||
tokenRecorded = true;
|
tokenRecorded = true;
|
||||||
}
|
}
|
||||||
if (token == ')') {
|
if (token == ')') {
|
||||||
if (in->mac->argc == 1 && tokenRecorded == 0)
|
if (in->mac->args.size() == 1 && tokenRecorded == 0)
|
||||||
break;
|
break;
|
||||||
arg++;
|
arg++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
arg++;
|
arg++;
|
||||||
} while (arg < in->mac->argc);
|
} while (arg < in->mac->args.size());
|
||||||
|
|
||||||
if (arg < in->mac->argc)
|
if (arg < in->mac->args.size())
|
||||||
parseContext.ppError(loc, "Too few args in Macro", "macro expansion", GetAtomString(atom));
|
parseContext.ppError(loc, "Too few args in Macro", "macro expansion", atomStrings.getString(macroAtom));
|
||||||
else if (token != ')') {
|
else if (token != ')') {
|
||||||
depth=0;
|
depth=0;
|
||||||
while (token != EndOfInput && (depth > 0 || token != ')')) {
|
while (token != EndOfInput && (depth > 0 || token != ')')) {
|
||||||
|
@ -1131,19 +1247,22 @@ int TPpContext::MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == EndOfInput) {
|
if (token == EndOfInput) {
|
||||||
parseContext.ppError(loc, "End of input in macro", "macro expansion", GetAtomString(atom));
|
parseContext.ppError(loc, "End of input in macro", "macro expansion", atomStrings.getString(macroAtom));
|
||||||
delete in;
|
delete in;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
parseContext.ppError(loc, "Too many args in macro", "macro expansion", GetAtomString(atom));
|
parseContext.ppError(loc, "Too many args in macro", "macro expansion", atomStrings.getString(macroAtom));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < in->mac->argc; i++)
|
|
||||||
in->args[i] = PrescanMacroArg(in->args[i], ppToken, newLineOkay);
|
// We need both expanded and non-expanded forms of the argument, for whether or
|
||||||
|
// not token pasting will be applied later when the argument is consumed next to ##.
|
||||||
|
for (size_t i = 0; i < in->mac->args.size(); i++)
|
||||||
|
in->expandedArgs[i] = PrescanMacroArg(*in->args[i], ppToken, newLineOkay);
|
||||||
}
|
}
|
||||||
|
|
||||||
pushInput(in);
|
pushInput(in);
|
||||||
sym->mac.busy = 1;
|
macro->busy = 1;
|
||||||
RewindTokenStream(sym->mac.body);
|
macro->body.reset();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
Copyright (c) 2002, NVIDIA Corporation.
|
||||||
|
@ -76,16 +76,13 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
//
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
// atom.c
|
|
||||||
//
|
|
||||||
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <stdio.h>
|
#include <cstring>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "PpContext.h"
|
#include "PpContext.h"
|
||||||
#include "PpTokens.h"
|
#include "PpTokens.h"
|
||||||
|
@ -98,8 +95,36 @@ const struct {
|
||||||
int val;
|
int val;
|
||||||
const char* str;
|
const char* str;
|
||||||
} tokens[] = {
|
} tokens[] = {
|
||||||
|
|
||||||
|
{ PPAtomAddAssign, "+=" },
|
||||||
|
{ PPAtomSubAssign, "-=" },
|
||||||
|
{ PPAtomMulAssign, "*=" },
|
||||||
|
{ PPAtomDivAssign, "/=" },
|
||||||
|
{ PPAtomModAssign, "%=" },
|
||||||
|
|
||||||
|
{ PpAtomRight, ">>" },
|
||||||
|
{ PpAtomLeft, "<<" },
|
||||||
|
{ PpAtomAnd, "&&" },
|
||||||
|
{ PpAtomOr, "||" },
|
||||||
|
{ PpAtomXor, "^^" },
|
||||||
|
|
||||||
|
{ PpAtomRightAssign, ">>=" },
|
||||||
|
{ PpAtomLeftAssign, "<<=" },
|
||||||
|
{ PpAtomAndAssign, "&=" },
|
||||||
|
{ PpAtomOrAssign, "|=" },
|
||||||
|
{ PpAtomXorAssign, "^=" },
|
||||||
|
|
||||||
|
{ PpAtomEQ, "==" },
|
||||||
|
{ PpAtomNE, "!=" },
|
||||||
|
{ PpAtomGE, ">=" },
|
||||||
|
{ PpAtomLE, "<=" },
|
||||||
|
|
||||||
|
{ PpAtomDecrement, "--" },
|
||||||
|
{ PpAtomIncrement, "++" },
|
||||||
|
|
||||||
|
{ PpAtomColonColon, "::" },
|
||||||
|
|
||||||
{ PpAtomDefine, "define" },
|
{ PpAtomDefine, "define" },
|
||||||
{ PpAtomDefined, "defined" },
|
|
||||||
{ PpAtomUndef, "undef" },
|
{ PpAtomUndef, "undef" },
|
||||||
{ PpAtomIf, "if" },
|
{ PpAtomIf, "if" },
|
||||||
{ PpAtomElif, "elif" },
|
{ PpAtomElif, "elif" },
|
||||||
|
@ -122,55 +147,19 @@ const struct {
|
||||||
{ PpAtomVersionMacro, "__VERSION__" },
|
{ PpAtomVersionMacro, "__VERSION__" },
|
||||||
|
|
||||||
{ PpAtomInclude, "include" },
|
{ PpAtomInclude, "include" },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
//
|
|
||||||
// Map a new or existing string to an atom, inventing a new atom if necessary.
|
|
||||||
//
|
|
||||||
int TPpContext::LookUpAddString(const char* s)
|
|
||||||
{
|
|
||||||
auto it = atomMap.find(s);
|
|
||||||
if (it == atomMap.end()) {
|
|
||||||
AddAtomFixed(s, nextAtom);
|
|
||||||
return nextAtom++;
|
|
||||||
} else
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Map an already created atom to its string.
|
|
||||||
//
|
|
||||||
const char* TPpContext::GetAtomString(int atom)
|
|
||||||
{
|
|
||||||
if ((size_t)atom >= stringMap.size())
|
|
||||||
return "<bad token>";
|
|
||||||
|
|
||||||
const TString* atomString = stringMap[atom];
|
|
||||||
|
|
||||||
return atomString ? atomString->c_str() : "<bad token>";
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Add forced mapping of string to atom.
|
|
||||||
//
|
|
||||||
void TPpContext::AddAtomFixed(const char* s, int atom)
|
|
||||||
{
|
|
||||||
auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
|
|
||||||
if (stringMap.size() < (size_t)atom + 1)
|
|
||||||
stringMap.resize(atom + 100, 0);
|
|
||||||
stringMap[atom] = &it->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize the atom table.
|
// Initialize the atom table.
|
||||||
//
|
//
|
||||||
void TPpContext::InitAtomTable()
|
TStringAtomMap::TStringAtomMap()
|
||||||
{
|
{
|
||||||
|
badToken.assign("<bad token>");
|
||||||
|
|
||||||
// Add single character tokens to the atom table:
|
// Add single character tokens to the atom table:
|
||||||
const char* s = "~!%^&*()-+=|,.<>/?;:[]{}#\\";
|
const char* s = "~!%^&*()-+=|,.<>/?;:[]{}#\\";
|
||||||
char t[2];
|
char t[2];
|
||||||
|
@ -178,13 +167,13 @@ void TPpContext::InitAtomTable()
|
||||||
t[1] = '\0';
|
t[1] = '\0';
|
||||||
while (*s) {
|
while (*s) {
|
||||||
t[0] = *s;
|
t[0] = *s;
|
||||||
AddAtomFixed(t, s[0]);
|
addAtomFixed(t, s[0]);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add multiple character scanner tokens :
|
// Add multiple character scanner tokens :
|
||||||
for (size_t ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
|
for (size_t ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
|
||||||
AddAtomFixed(tokens[ii].str, tokens[ii].val);
|
addAtomFixed(tokens[ii].str, tokens[ii].val);
|
||||||
|
|
||||||
nextAtom = PpAtomLast;
|
nextAtom = PpAtomLast;
|
||||||
}
|
}
|
||||||
|
|
50
Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp
vendored
Normal file → Executable file
50
Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp
vendored
Normal file → Executable file
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
Copyright (c) 2002, NVIDIA Corporation.
|
||||||
|
@ -76,32 +76,28 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
\****************************************************************************/
|
\****************************************************************************/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <cstdlib>
|
||||||
#include <stdlib.h>
|
#include <locale>
|
||||||
|
|
||||||
#include "PpContext.h"
|
#include "PpContext.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) :
|
||||||
preamble(0), strings(0), parseContext(pc), includer(inclr), inComment(false),
|
preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false),
|
||||||
rootFileName(rootFileName),
|
rootFileName(rootFileName),
|
||||||
currentSourceFile(rootFileName)
|
currentSourceFile(rootFileName)
|
||||||
{
|
{
|
||||||
InitAtomTable();
|
|
||||||
InitScanner();
|
|
||||||
|
|
||||||
ifdepth = 0;
|
ifdepth = 0;
|
||||||
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
|
for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++)
|
||||||
elseSeen[elsetracker] = false;
|
elseSeen[elsetracker] = false;
|
||||||
elsetracker = 0;
|
elsetracker = 0;
|
||||||
|
|
||||||
|
strtodStream.imbue(std::locale::classic());
|
||||||
}
|
}
|
||||||
|
|
||||||
TPpContext::~TPpContext()
|
TPpContext::~TPpContext()
|
||||||
{
|
{
|
||||||
for (TSymbolMap::iterator it = symbols.begin(); it != symbols.end(); ++it)
|
|
||||||
delete it->second->mac.body;
|
|
||||||
mem_FreePool(pool);
|
|
||||||
delete [] preamble;
|
delete [] preamble;
|
||||||
|
|
||||||
// free up the inputStack
|
// free up the inputStack
|
||||||
|
|
306
Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
vendored
Normal file → Executable file
306
Externals/glslang/glslang/MachineIndependent/preprocessor/PpContext.h
vendored
Normal file → Executable file
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
Copyright (c) 2002, NVIDIA Corporation.
|
||||||
|
@ -80,6 +80,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "../ParseHelper.h"
|
#include "../ParseHelper.h"
|
||||||
|
|
||||||
|
@ -92,30 +93,94 @@ namespace glslang {
|
||||||
|
|
||||||
class TPpToken {
|
class TPpToken {
|
||||||
public:
|
public:
|
||||||
TPpToken() : token(0), space(false), ival(0), dval(0.0), atom(0)
|
TPpToken() { clear(); }
|
||||||
|
void clear()
|
||||||
{
|
{
|
||||||
|
space = false;
|
||||||
|
i64val = 0;
|
||||||
loc.init();
|
loc.init();
|
||||||
name[0] = 0;
|
name[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used for comparing macro definitions, so checks what is relevant for that.
|
||||||
bool operator==(const TPpToken& right)
|
bool operator==(const TPpToken& right)
|
||||||
{
|
{
|
||||||
return token == right.token && atom == right.atom &&
|
return space == right.space &&
|
||||||
ival == right.ival && dval == right.dval &&
|
ival == right.ival && dval == right.dval && i64val == right.i64val &&
|
||||||
strcmp(name, right.name) == 0;
|
strncmp(name, right.name, MaxTokenLength) == 0;
|
||||||
}
|
}
|
||||||
bool operator!=(const TPpToken& right) { return ! operator==(right); }
|
bool operator!=(const TPpToken& right) { return ! operator==(right); }
|
||||||
|
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
int token;
|
// True if a space (for white space or a removed comment) should also be
|
||||||
bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
|
// recognized, in front of the token returned:
|
||||||
|
bool space;
|
||||||
|
// Numeric value of the token:
|
||||||
|
union {
|
||||||
int ival;
|
int ival;
|
||||||
double dval;
|
double dval;
|
||||||
long long i64val;
|
long long i64val;
|
||||||
int atom;
|
};
|
||||||
|
// Text string of the token:
|
||||||
char name[MaxTokenLength + 1];
|
char name[MaxTokenLength + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TStringAtomMap {
|
||||||
|
//
|
||||||
|
// Implementation is in PpAtom.cpp
|
||||||
|
//
|
||||||
|
// Maintain a bi-directional mapping between relevant preprocessor strings and
|
||||||
|
// "atoms" which a unique integers (small, contiguous, not hash-like) per string.
|
||||||
|
//
|
||||||
|
public:
|
||||||
|
TStringAtomMap();
|
||||||
|
|
||||||
|
// Map string -> atom.
|
||||||
|
// Return 0 if no existing string.
|
||||||
|
int getAtom(const char* s) const
|
||||||
|
{
|
||||||
|
auto it = atomMap.find(s);
|
||||||
|
return it == atomMap.end() ? 0 : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map a new or existing string -> atom, inventing a new atom if necessary.
|
||||||
|
int getAddAtom(const char* s)
|
||||||
|
{
|
||||||
|
int atom = getAtom(s);
|
||||||
|
if (atom == 0) {
|
||||||
|
atom = nextAtom++;
|
||||||
|
addAtomFixed(s, atom);
|
||||||
|
}
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map atom -> string.
|
||||||
|
const char* getString(int atom) const { return stringMap[atom]->c_str(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TStringAtomMap(TStringAtomMap&);
|
||||||
|
TStringAtomMap& operator=(TStringAtomMap&);
|
||||||
|
|
||||||
|
TUnorderedMap<TString, int> atomMap;
|
||||||
|
TVector<const TString*> stringMap; // these point into the TString in atomMap
|
||||||
|
int nextAtom;
|
||||||
|
|
||||||
|
// Bad source characters can lead to bad atoms, so gracefully handle those by
|
||||||
|
// pre-filling the table with them (to avoid if tests later).
|
||||||
|
TString badToken;
|
||||||
|
|
||||||
|
// Add bi-directional mappings:
|
||||||
|
// - string -> atom
|
||||||
|
// - atom -> string
|
||||||
|
void addAtomFixed(const char* s, int atom)
|
||||||
|
{
|
||||||
|
auto it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
|
||||||
|
if (stringMap.size() < (size_t)atom + 1)
|
||||||
|
stringMap.resize(atom + 100, &badToken);
|
||||||
|
stringMap[atom] = &it->first;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class TInputScanner;
|
class TInputScanner;
|
||||||
|
|
||||||
// This class is the result of turning a huge pile of C code communicating through globals
|
// This class is the result of turning a huge pile of C code communicating through globals
|
||||||
|
@ -128,7 +193,8 @@ public:
|
||||||
|
|
||||||
void setPreamble(const char* preamble, size_t length);
|
void setPreamble(const char* preamble, size_t length);
|
||||||
|
|
||||||
const char* tokenize(TPpToken* ppToken);
|
int tokenize(TPpToken& ppToken);
|
||||||
|
int tokenPaste(int token, TPpToken&);
|
||||||
|
|
||||||
class tInput {
|
class tInput {
|
||||||
public:
|
public:
|
||||||
|
@ -138,6 +204,9 @@ public:
|
||||||
virtual int scan(TPpToken*) = 0;
|
virtual int scan(TPpToken*) = 0;
|
||||||
virtual int getch() = 0;
|
virtual int getch() = 0;
|
||||||
virtual void ungetch() = 0;
|
virtual void ungetch() = 0;
|
||||||
|
virtual bool peekPasting() { return false; } // true when about to see ##
|
||||||
|
virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define)
|
||||||
|
virtual bool isMacroInput() { return false; }
|
||||||
|
|
||||||
// Will be called when we start reading tokens from this instance
|
// Will be called when we start reading tokens from this instance
|
||||||
virtual void notifyActivated() {}
|
virtual void notifyActivated() {}
|
||||||
|
@ -162,50 +231,57 @@ public:
|
||||||
inputStack.pop_back();
|
inputStack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TokenStream {
|
//
|
||||||
|
// From PpTokens.cpp
|
||||||
|
//
|
||||||
|
|
||||||
|
class TokenStream {
|
||||||
|
public:
|
||||||
TokenStream() : current(0) { }
|
TokenStream() : current(0) { }
|
||||||
|
|
||||||
|
void putToken(int token, TPpToken* ppToken);
|
||||||
|
int getToken(TParseContextBase&, TPpToken*);
|
||||||
|
bool atEnd() { return current >= data.size(); }
|
||||||
|
bool peekTokenizedPasting(bool lastTokenPastes);
|
||||||
|
bool peekUntokenizedPasting();
|
||||||
|
void reset() { current = 0; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void putSubtoken(char);
|
||||||
|
int getSubtoken();
|
||||||
|
void ungetSubtoken();
|
||||||
|
|
||||||
TVector<unsigned char> data;
|
TVector<unsigned char> data;
|
||||||
size_t current;
|
size_t current;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MemoryPool {
|
|
||||||
struct chunk *next;
|
|
||||||
uintptr_t free, end;
|
|
||||||
size_t chunksize;
|
|
||||||
uintptr_t alignmask;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// From Pp.cpp
|
// From Pp.cpp
|
||||||
//
|
//
|
||||||
|
|
||||||
struct MacroSymbol {
|
struct MacroSymbol {
|
||||||
MacroSymbol() : argc(0), args(0), body(0), busy(0), undef(0) { }
|
MacroSymbol() : emptyArgs(0), busy(0), undef(0) { }
|
||||||
int argc;
|
TVector<int> args;
|
||||||
int *args;
|
TokenStream body;
|
||||||
TokenStream *body;
|
unsigned emptyArgs : 1;
|
||||||
unsigned busy:1;
|
unsigned busy : 1;
|
||||||
unsigned undef:1;
|
unsigned undef : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Symbol {
|
typedef TMap<int, MacroSymbol> TSymbolMap;
|
||||||
int atom;
|
TSymbolMap macroDefs; // map atoms to macro definitions
|
||||||
MacroSymbol mac;
|
MacroSymbol* lookupMacroDef(int atom)
|
||||||
};
|
{
|
||||||
|
auto existingMacroIt = macroDefs.find(atom);
|
||||||
struct SymbolList {
|
return (existingMacroIt == macroDefs.end()) ? nullptr : &(existingMacroIt->second);
|
||||||
struct SymbolList_Rec *next;
|
}
|
||||||
Symbol *symb;
|
void addMacroDef(int atom, MacroSymbol& macroDef) { macroDefs[atom] = macroDef; }
|
||||||
};
|
|
||||||
|
|
||||||
MemoryPool *pool;
|
|
||||||
typedef TMap<int, Symbol*> TSymbolMap;
|
|
||||||
TSymbolMap symbols; // this has light use... just defined macros
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TPpContext(TPpContext&);
|
TPpContext(TPpContext&);
|
||||||
TPpContext& operator=(TPpContext&);
|
TPpContext& operator=(TPpContext&);
|
||||||
|
|
||||||
|
TStringAtomMap atomStrings;
|
||||||
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
|
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
|
||||||
int preambleLength;
|
int preambleLength;
|
||||||
char** strings; // official strings of shader, starting a string 0 line 1
|
char** strings; // official strings of shader, starting a string 0 line 1
|
||||||
|
@ -218,7 +294,7 @@ protected:
|
||||||
TParseContextBase& parseContext;
|
TParseContextBase& parseContext;
|
||||||
|
|
||||||
// Get the next token from *stack* of input sources, popping input sources
|
// Get the next token from *stack* of input sources, popping input sources
|
||||||
// that are out of tokens, down until an input sources is found that has a token.
|
// that are out of tokens, down until an input source is found that has a token.
|
||||||
// Return EndOfInput when there are no more tokens to be found by doing this.
|
// Return EndOfInput when there are no more tokens to be found by doing this.
|
||||||
int scanToken(TPpToken* ppToken)
|
int scanToken(TPpToken* ppToken)
|
||||||
{
|
{
|
||||||
|
@ -226,7 +302,7 @@ protected:
|
||||||
|
|
||||||
while (! inputStack.empty()) {
|
while (! inputStack.empty()) {
|
||||||
token = inputStack.back()->scan(ppToken);
|
token = inputStack.back()->scan(ppToken);
|
||||||
if (token != EndOfInput)
|
if (token != EndOfInput || inputStack.empty())
|
||||||
break;
|
break;
|
||||||
popInput();
|
popInput();
|
||||||
}
|
}
|
||||||
|
@ -235,9 +311,11 @@ protected:
|
||||||
}
|
}
|
||||||
int getChar() { return inputStack.back()->getch(); }
|
int getChar() { return inputStack.back()->getch(); }
|
||||||
void ungetChar() { inputStack.back()->ungetch(); }
|
void ungetChar() { inputStack.back()->ungetch(); }
|
||||||
|
bool peekPasting() { return !inputStack.empty() && inputStack.back()->peekPasting(); }
|
||||||
|
bool endOfReplacementList() { return inputStack.empty() || inputStack.back()->endOfReplacementList(); }
|
||||||
|
bool isMacroInput() { return inputStack.size() > 0 && inputStack.back()->isMacroInput(); }
|
||||||
|
|
||||||
static const int maxMacroArgs = 64;
|
static const int maxIfNesting = 65;
|
||||||
static const int maxIfNesting = 64;
|
|
||||||
|
|
||||||
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
|
int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor)
|
||||||
bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
|
bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth
|
||||||
|
@ -245,24 +323,35 @@ protected:
|
||||||
|
|
||||||
class tMacroInput : public tInput {
|
class tMacroInput : public tInput {
|
||||||
public:
|
public:
|
||||||
tMacroInput(TPpContext* pp) : tInput(pp) { }
|
tMacroInput(TPpContext* pp) : tInput(pp), prepaste(false), postpaste(false) { }
|
||||||
virtual ~tMacroInput()
|
virtual ~tMacroInput()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < args.size(); ++i)
|
for (size_t i = 0; i < args.size(); ++i)
|
||||||
delete args[i];
|
delete args[i];
|
||||||
|
for (size_t i = 0; i < expandedArgs.size(); ++i)
|
||||||
|
delete expandedArgs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int scan(TPpToken*);
|
virtual int scan(TPpToken*) override;
|
||||||
virtual int getch() { assert(0); return EndOfInput; }
|
virtual int getch() override { assert(0); return EndOfInput; }
|
||||||
virtual void ungetch() { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
|
bool peekPasting() override { return prepaste; }
|
||||||
|
bool endOfReplacementList() override { return mac->body.atEnd(); }
|
||||||
|
bool isMacroInput() override { return true; }
|
||||||
|
|
||||||
MacroSymbol *mac;
|
MacroSymbol *mac;
|
||||||
TVector<TokenStream*> args;
|
TVector<TokenStream*> args;
|
||||||
|
TVector<TokenStream*> expandedArgs;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool prepaste; // true if we are just before ##
|
||||||
|
bool postpaste; // true if we are right after ##
|
||||||
};
|
};
|
||||||
|
|
||||||
class tMarkerInput : public tInput {
|
class tMarkerInput : public tInput {
|
||||||
public:
|
public:
|
||||||
tMarkerInput(TPpContext* pp) : tInput(pp) { }
|
tMarkerInput(TPpContext* pp) : tInput(pp) { }
|
||||||
virtual int scan(TPpToken*)
|
virtual int scan(TPpToken*) override
|
||||||
{
|
{
|
||||||
if (done)
|
if (done)
|
||||||
return EndOfInput;
|
return EndOfInput;
|
||||||
|
@ -270,17 +359,17 @@ protected:
|
||||||
|
|
||||||
return marker;
|
return marker;
|
||||||
}
|
}
|
||||||
virtual int getch() { assert(0); return EndOfInput; }
|
virtual int getch() override { assert(0); return EndOfInput; }
|
||||||
virtual void ungetch() { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
static const int marker = -3;
|
static const int marker = -3;
|
||||||
};
|
};
|
||||||
|
|
||||||
class tZeroInput : public tInput {
|
class tZeroInput : public tInput {
|
||||||
public:
|
public:
|
||||||
tZeroInput(TPpContext* pp) : tInput(pp) { }
|
tZeroInput(TPpContext* pp) : tInput(pp) { }
|
||||||
virtual int scan(TPpToken*);
|
virtual int scan(TPpToken*) override;
|
||||||
virtual int getch() { assert(0); return EndOfInput; }
|
virtual int getch() override { assert(0); return EndOfInput; }
|
||||||
virtual void ungetch() { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<tInput*> inputStack;
|
std::vector<tInput*> inputStack;
|
||||||
|
@ -294,7 +383,6 @@ protected:
|
||||||
// Used to obtain #include content.
|
// Used to obtain #include content.
|
||||||
TShader::Includer& includer;
|
TShader::Includer& includer;
|
||||||
|
|
||||||
int InitCPP();
|
|
||||||
int CPPdefine(TPpToken * ppToken);
|
int CPPdefine(TPpToken * ppToken);
|
||||||
int CPPundef(TPpToken * ppToken);
|
int CPPundef(TPpToken * ppToken);
|
||||||
int CPPelse(int matchelse, TPpToken * ppToken);
|
int CPPelse(int matchelse, TPpToken * ppToken);
|
||||||
|
@ -310,44 +398,34 @@ protected:
|
||||||
int CPPversion(TPpToken * ppToken);
|
int CPPversion(TPpToken * ppToken);
|
||||||
int CPPextension(TPpToken * ppToken);
|
int CPPextension(TPpToken * ppToken);
|
||||||
int readCPPline(TPpToken * ppToken);
|
int readCPPline(TPpToken * ppToken);
|
||||||
TokenStream* PrescanMacroArg(TokenStream *a, TPpToken * ppToken, bool newLineOkay);
|
int scanHeaderName(TPpToken* ppToken, char delimit);
|
||||||
int MacroExpand(int atom, TPpToken* ppToken, bool expandUndef, bool newLineOkay);
|
TokenStream* PrescanMacroArg(TokenStream&, TPpToken*, bool newLineOkay);
|
||||||
|
int MacroExpand(TPpToken* ppToken, bool expandUndef, bool newLineOkay);
|
||||||
//
|
|
||||||
// from PpSymbols.cpp
|
|
||||||
//
|
|
||||||
Symbol *NewSymbol(int name);
|
|
||||||
Symbol *AddSymbol(int atom);
|
|
||||||
Symbol *LookUpSymbol(int atom);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// From PpTokens.cpp
|
// From PpTokens.cpp
|
||||||
//
|
//
|
||||||
void lAddByte(TokenStream *fTok, unsigned char fVal);
|
void pushTokenStreamInput(TokenStream&, bool pasting = false);
|
||||||
int lReadByte(TokenStream *pTok);
|
void UngetToken(int token, TPpToken*);
|
||||||
void lUnreadByte(TokenStream *pTok);
|
|
||||||
void RecordToken(TokenStream* pTok, int token, TPpToken* ppToken);
|
|
||||||
void RewindTokenStream(TokenStream *pTok);
|
|
||||||
int ReadToken(TokenStream* pTok, TPpToken* ppToken);
|
|
||||||
void pushTokenStreamInput(TokenStream *ts);
|
|
||||||
void UngetToken(int token, TPpToken* ppToken);
|
|
||||||
|
|
||||||
class tTokenInput : public tInput {
|
class tTokenInput : public tInput {
|
||||||
public:
|
public:
|
||||||
tTokenInput(TPpContext* pp, TokenStream* t) : tInput(pp), tokens(t) { }
|
tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : tInput(pp), tokens(t), lastTokenPastes(prepasting) { }
|
||||||
virtual int scan(TPpToken *);
|
virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); }
|
||||||
virtual int getch() { assert(0); return EndOfInput; }
|
virtual int getch() override { assert(0); return EndOfInput; }
|
||||||
virtual void ungetch() { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
|
virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); }
|
||||||
protected:
|
protected:
|
||||||
TokenStream *tokens;
|
TokenStream* tokens;
|
||||||
|
bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token
|
||||||
};
|
};
|
||||||
|
|
||||||
class tUngotTokenInput : public tInput {
|
class tUngotTokenInput : public tInput {
|
||||||
public:
|
public:
|
||||||
tUngotTokenInput(TPpContext* pp, int t, TPpToken* p) : tInput(pp), token(t), lval(*p) { }
|
tUngotTokenInput(TPpContext* pp, int t, TPpToken* p) : tInput(pp), token(t), lval(*p) { }
|
||||||
virtual int scan(TPpToken *);
|
virtual int scan(TPpToken *) override;
|
||||||
virtual int getch() { assert(0); return EndOfInput; }
|
virtual int getch() override { assert(0); return EndOfInput; }
|
||||||
virtual void ungetch() { assert(0); }
|
virtual void ungetch() override { assert(0); }
|
||||||
protected:
|
protected:
|
||||||
int token;
|
int token;
|
||||||
TPpToken lval;
|
TPpToken lval;
|
||||||
|
@ -359,12 +437,12 @@ protected:
|
||||||
class tStringInput : public tInput {
|
class tStringInput : public tInput {
|
||||||
public:
|
public:
|
||||||
tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
|
tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { }
|
||||||
virtual int scan(TPpToken*);
|
virtual int scan(TPpToken*) override;
|
||||||
|
|
||||||
// Scanner used to get source stream characters.
|
// Scanner used to get source stream characters.
|
||||||
// - Escaped newlines are handled here, invisibly to the caller.
|
// - Escaped newlines are handled here, invisibly to the caller.
|
||||||
// - All forms of newline are handled, and turned into just a '\n'.
|
// - All forms of newline are handled, and turned into just a '\n'.
|
||||||
int getch()
|
int getch() override
|
||||||
{
|
{
|
||||||
int ch = input->get();
|
int ch = input->get();
|
||||||
|
|
||||||
|
@ -402,7 +480,7 @@ protected:
|
||||||
// handled here, invisibly to the caller, meaning have to undo exactly
|
// handled here, invisibly to the caller, meaning have to undo exactly
|
||||||
// what getch() above does (e.g., don't leave things in the middle of a
|
// what getch() above does (e.g., don't leave things in the middle of a
|
||||||
// sequence of escaped newlines).
|
// sequence of escaped newlines).
|
||||||
void ungetch()
|
void ungetch() override
|
||||||
{
|
{
|
||||||
input->unget();
|
input->unget();
|
||||||
|
|
||||||
|
@ -446,18 +524,18 @@ protected:
|
||||||
TPpContext* pp)
|
TPpContext* pp)
|
||||||
: tInput(pp),
|
: tInput(pp),
|
||||||
prologue_(prologue),
|
prologue_(prologue),
|
||||||
includedFile_(includedFile),
|
|
||||||
epilogue_(epilogue),
|
epilogue_(epilogue),
|
||||||
|
includedFile_(includedFile),
|
||||||
scanner(3, strings, lengths, names, 0, 0, true),
|
scanner(3, strings, lengths, names, 0, 0, true),
|
||||||
prevScanner(nullptr),
|
prevScanner(nullptr),
|
||||||
stringInput(pp, scanner)
|
stringInput(pp, scanner)
|
||||||
{
|
{
|
||||||
strings[0] = prologue_.data();
|
strings[0] = prologue_.data();
|
||||||
strings[1] = includedFile_->file_data;
|
strings[1] = includedFile_->headerData;
|
||||||
strings[2] = epilogue_.data();
|
strings[2] = epilogue_.data();
|
||||||
|
|
||||||
lengths[0] = prologue_.size();
|
lengths[0] = prologue_.size();
|
||||||
lengths[1] = includedFile_->file_length;
|
lengths[1] = includedFile_->headerLength;
|
||||||
lengths[2] = epilogue_.size();
|
lengths[2] = epilogue_.size();
|
||||||
|
|
||||||
scanner.setLine(startLoc.line);
|
scanner.setLine(startLoc.line);
|
||||||
|
@ -498,7 +576,7 @@ protected:
|
||||||
// Points to the IncludeResult that this TokenizableIncludeFile represents.
|
// Points to the IncludeResult that this TokenizableIncludeFile represents.
|
||||||
TShader::Includer::IncludeResult* includedFile_;
|
TShader::Includer::IncludeResult* includedFile_;
|
||||||
|
|
||||||
// Will point to prologue_, includedFile_->file_data and epilogue_
|
// Will point to prologue_, includedFile_->headerData and epilogue_
|
||||||
// This is passed to scanner constructor.
|
// This is passed to scanner constructor.
|
||||||
// These do not own the storage and it must remain valid until this
|
// These do not own the storage and it must remain valid until this
|
||||||
// object has been destroyed.
|
// object has been destroyed.
|
||||||
|
@ -516,14 +594,14 @@ protected:
|
||||||
tStringInput stringInput;
|
tStringInput stringInput;
|
||||||
};
|
};
|
||||||
|
|
||||||
int InitScanner();
|
|
||||||
int ScanFromString(char* s);
|
int ScanFromString(char* s);
|
||||||
void missingEndifCheck();
|
void missingEndifCheck();
|
||||||
int lFloatConst(int len, int ch, TPpToken* ppToken);
|
int lFloatConst(int len, int ch, TPpToken* ppToken);
|
||||||
|
int characterLiteral(TPpToken* ppToken);
|
||||||
|
|
||||||
void push_include(TShader::Includer::IncludeResult* result)
|
void push_include(TShader::Includer::IncludeResult* result)
|
||||||
{
|
{
|
||||||
currentSourceFile = result->file_name;
|
currentSourceFile = result->headerName;
|
||||||
includeStack.push(result);
|
includeStack.push(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,36 +613,16 @@ protected:
|
||||||
if (includeStack.empty()) {
|
if (includeStack.empty()) {
|
||||||
currentSourceFile = rootFileName;
|
currentSourceFile = rootFileName;
|
||||||
} else {
|
} else {
|
||||||
currentSourceFile = includeStack.top()->file_name;
|
currentSourceFile = includeStack.top()->headerName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inComment;
|
bool inComment;
|
||||||
|
std::string rootFileName;
|
||||||
//
|
|
||||||
// From PpAtom.cpp
|
|
||||||
//
|
|
||||||
typedef TUnorderedMap<TString, int> TAtomMap;
|
|
||||||
typedef TVector<const TString*> TStringMap;
|
|
||||||
|
|
||||||
TAtomMap atomMap;
|
|
||||||
TStringMap stringMap;
|
|
||||||
std::stack<TShader::Includer::IncludeResult*> includeStack;
|
std::stack<TShader::Includer::IncludeResult*> includeStack;
|
||||||
std::string currentSourceFile;
|
std::string currentSourceFile;
|
||||||
std::string rootFileName;
|
|
||||||
int nextAtom;
|
|
||||||
void InitAtomTable();
|
|
||||||
void AddAtomFixed(const char* s, int atom);
|
|
||||||
int LookUpAddString(const char* s);
|
|
||||||
const char* GetAtomString(int atom);
|
|
||||||
|
|
||||||
//
|
std::istringstream strtodStream;
|
||||||
// From PpMemory.cpp
|
|
||||||
//
|
|
||||||
MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
|
|
||||||
void mem_FreePool(MemoryPool*);
|
|
||||||
void *mem_Alloc(MemoryPool* p, size_t size);
|
|
||||||
int mem_AddCleanup(MemoryPool* p, void (*fn)(void *, void*), void* arg1, void* arg2);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
@ -1,162 +0,0 @@
|
||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//Copyright (C) 2013 LunarG, 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.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "PpContext.h"
|
|
||||||
|
|
||||||
// default alignment and chunksize, if called with 0 arguments
|
|
||||||
#define CHUNKSIZE (64*1024)
|
|
||||||
#define ALIGN 8
|
|
||||||
|
|
||||||
namespace glslang {
|
|
||||||
|
|
||||||
struct chunk {
|
|
||||||
struct chunk *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
TPpContext::MemoryPool* TPpContext::mem_CreatePool(size_t chunksize, unsigned int align)
|
|
||||||
{
|
|
||||||
if (align == 0)
|
|
||||||
align = ALIGN;
|
|
||||||
if (chunksize == 0)
|
|
||||||
chunksize = CHUNKSIZE;
|
|
||||||
if (align & (align - 1))
|
|
||||||
return nullptr;
|
|
||||||
if (chunksize < sizeof(MemoryPool))
|
|
||||||
return nullptr;
|
|
||||||
if (chunksize & (align - 1))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
MemoryPool *pool = (MemoryPool*)malloc(chunksize);
|
|
||||||
if (! pool)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
pool->next = 0;
|
|
||||||
pool->chunksize = chunksize;
|
|
||||||
pool->alignmask = (uintptr_t)(align) - 1;
|
|
||||||
pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
|
|
||||||
pool->end = (uintptr_t)pool + chunksize;
|
|
||||||
|
|
||||||
return pool;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TPpContext::mem_FreePool(MemoryPool *pool)
|
|
||||||
{
|
|
||||||
struct chunk *p, *next;
|
|
||||||
|
|
||||||
for (p = (struct chunk *)pool; p; p = next) {
|
|
||||||
next = p->next;
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void* TPpContext::mem_Alloc(MemoryPool *pool, size_t size)
|
|
||||||
{
|
|
||||||
struct chunk *ch;
|
|
||||||
void *rv = (void *)pool->free;
|
|
||||||
size = (size + pool->alignmask) & ~pool->alignmask;
|
|
||||||
if (size <= 0) size = pool->alignmask;
|
|
||||||
pool->free += size;
|
|
||||||
if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
|
|
||||||
size_t minreq = (size + sizeof(struct chunk) + pool->alignmask) & ~pool->alignmask;
|
|
||||||
pool->free = (uintptr_t)rv;
|
|
||||||
if (minreq >= pool->chunksize) {
|
|
||||||
// request size is too big for the chunksize, so allocate it as
|
|
||||||
// a single chunk of the right size
|
|
||||||
ch = (struct chunk*)malloc(minreq);
|
|
||||||
if (! ch)
|
|
||||||
return nullptr;
|
|
||||||
} else {
|
|
||||||
ch = (struct chunk*)malloc(pool->chunksize);
|
|
||||||
if (! ch)
|
|
||||||
return nullptr;
|
|
||||||
pool->free = (uintptr_t)ch + minreq;
|
|
||||||
pool->end = (uintptr_t)ch + pool->chunksize;
|
|
||||||
}
|
|
||||||
ch->next = pool->next;
|
|
||||||
pool->next = ch;
|
|
||||||
rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace glslang
|
|
744
Externals/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
vendored
Normal file → Executable file
744
Externals/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp
vendored
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
|
@ -1,135 +0,0 @@
|
||||||
//
|
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
|
||||||
//Copyright (C) 2013 LunarG, 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.
|
|
||||||
//
|
|
||||||
/****************************************************************************\
|
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
|
||||||
|
|
||||||
NVIDIA Corporation("NVIDIA") supplies this software to you in
|
|
||||||
consideration of your agreement to the following terms, and your use,
|
|
||||||
installation, modification or redistribution of this NVIDIA software
|
|
||||||
constitutes acceptance of these terms. If you do not agree with these
|
|
||||||
terms, please do not use, install, modify or redistribute this NVIDIA
|
|
||||||
software.
|
|
||||||
|
|
||||||
In consideration of your agreement to abide by the following terms, and
|
|
||||||
subject to these terms, NVIDIA grants you a personal, non-exclusive
|
|
||||||
license, under NVIDIA's copyrights in this original NVIDIA software (the
|
|
||||||
"NVIDIA Software"), to use, reproduce, modify and redistribute the
|
|
||||||
NVIDIA Software, with or without modifications, in source and/or binary
|
|
||||||
forms; provided that if you redistribute the NVIDIA Software, you must
|
|
||||||
retain the copyright notice of NVIDIA, this notice and the following
|
|
||||||
text and disclaimers in all such redistributions of the NVIDIA Software.
|
|
||||||
Neither the name, trademarks, service marks nor logos of NVIDIA
|
|
||||||
Corporation may be used to endorse or promote products derived from the
|
|
||||||
NVIDIA Software without specific prior written permission from NVIDIA.
|
|
||||||
Except as expressly stated in this notice, no other rights or licenses
|
|
||||||
express or implied, are granted by NVIDIA herein, including but not
|
|
||||||
limited to any patent rights that may be infringed by your derivative
|
|
||||||
works or by other works in which the NVIDIA Software may be
|
|
||||||
incorporated. No hardware is licensed hereunder.
|
|
||||||
|
|
||||||
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
||||||
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
|
|
||||||
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
|
|
||||||
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
|
|
||||||
PRODUCTS.
|
|
||||||
|
|
||||||
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
|
|
||||||
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
||||||
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
||||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
|
|
||||||
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
|
|
||||||
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
|
|
||||||
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
|
|
||||||
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
\****************************************************************************/
|
|
||||||
//
|
|
||||||
// symbols.c
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "PpContext.h"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace glslang {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allocate a new symbol node;
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
TPpContext::Symbol* TPpContext::NewSymbol(int atom)
|
|
||||||
{
|
|
||||||
Symbol* lSymb;
|
|
||||||
char* pch;
|
|
||||||
size_t ii;
|
|
||||||
|
|
||||||
lSymb = (Symbol *) mem_Alloc(pool, sizeof(Symbol));
|
|
||||||
lSymb->atom = atom;
|
|
||||||
|
|
||||||
// Clear macro
|
|
||||||
pch = (char*) &lSymb->mac;
|
|
||||||
for (ii = 0; ii < sizeof(lSymb->mac); ii++)
|
|
||||||
*pch++ = 0;
|
|
||||||
|
|
||||||
return lSymb;
|
|
||||||
}
|
|
||||||
|
|
||||||
TPpContext::Symbol* TPpContext::AddSymbol(int atom)
|
|
||||||
{
|
|
||||||
Symbol *lSymb;
|
|
||||||
|
|
||||||
lSymb = NewSymbol(atom);
|
|
||||||
symbols[lSymb->atom] = lSymb;
|
|
||||||
|
|
||||||
return lSymb;
|
|
||||||
}
|
|
||||||
|
|
||||||
TPpContext::Symbol* TPpContext::LookUpSymbol(int atom)
|
|
||||||
{
|
|
||||||
TSymbolMap::iterator it = symbols.find(atom);
|
|
||||||
if (it == symbols.end())
|
|
||||||
return nullptr;
|
|
||||||
else
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace glslang
|
|
350
Externals/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
vendored
Normal file → Executable file
350
Externals/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp
vendored
Normal file → Executable file
|
@ -1,11 +1,11 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//Copyright (C) 2013 LunarG, Inc.
|
// Copyright (C) 2013 LunarG, Inc.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -19,18 +19,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
Copyright (c) 2002, NVIDIA Corporation.
|
||||||
|
@ -80,182 +80,242 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// For recording and playing back the stream of tokens in a macro definition.
|
// For recording and playing back the stream of tokens in a macro definition.
|
||||||
//
|
//
|
||||||
|
|
||||||
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
|
||||||
#define snprintf sprintf_s
|
#define snprintf sprintf_s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <stdio.h>
|
#include <cstring>
|
||||||
#include <string.h>
|
#include <cctype>
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "PpContext.h"
|
#include "PpContext.h"
|
||||||
#include "PpTokens.h"
|
#include "PpTokens.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal)
|
|
||||||
{
|
namespace {
|
||||||
fTok->data.push_back(fVal);
|
|
||||||
|
// When recording (and playing back) should the backing name string
|
||||||
|
// be saved (restored)?
|
||||||
|
bool SaveName(int atom)
|
||||||
|
{
|
||||||
|
switch (atom) {
|
||||||
|
case PpAtomIdentifier:
|
||||||
|
case PpAtomConstString:
|
||||||
|
case PpAtomConstInt:
|
||||||
|
case PpAtomConstUint:
|
||||||
|
case PpAtomConstInt64:
|
||||||
|
case PpAtomConstUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
|
case PpAtomConstFloat:
|
||||||
|
case PpAtomConstDouble:
|
||||||
|
case PpAtomConstFloat16:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When recording (and playing back) should the numeric value
|
||||||
|
// be saved (restored)?
|
||||||
|
bool SaveValue(int atom)
|
||||||
|
{
|
||||||
|
switch (atom) {
|
||||||
|
case PpAtomConstInt:
|
||||||
|
case PpAtomConstUint:
|
||||||
|
case PpAtomConstInt64:
|
||||||
|
case PpAtomConstUint64:
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
case PpAtomConstInt16:
|
||||||
|
case PpAtomConstUint16:
|
||||||
|
#endif
|
||||||
|
case PpAtomConstFloat:
|
||||||
|
case PpAtomConstDouble:
|
||||||
|
case PpAtomConstFloat16:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// push onto back of stream
|
||||||
* Get the next byte from a stream.
|
void TPpContext::TokenStream::putSubtoken(char subtoken)
|
||||||
*/
|
|
||||||
int TPpContext::lReadByte(TokenStream *pTok)
|
|
||||||
{
|
{
|
||||||
if (pTok->current < pTok->data.size())
|
data.push_back(static_cast<unsigned char>(subtoken));
|
||||||
return pTok->data[pTok->current++];
|
}
|
||||||
|
|
||||||
|
// get the next token in stream
|
||||||
|
int TPpContext::TokenStream::getSubtoken()
|
||||||
|
{
|
||||||
|
if (current < data.size())
|
||||||
|
return data[current++];
|
||||||
else
|
else
|
||||||
return EndOfInput;
|
return EndOfInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TPpContext::lUnreadByte(TokenStream *pTok)
|
// back up one position in the stream
|
||||||
|
void TPpContext::TokenStream::ungetSubtoken()
|
||||||
{
|
{
|
||||||
if (pTok->current > 0)
|
if (current > 0)
|
||||||
--pTok->current;
|
--current;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Add a complete token (including backing string) to the end of a list
|
||||||
* Add a token to the end of a list for later playback.
|
// for later playback.
|
||||||
*/
|
void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
|
||||||
void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
|
|
||||||
{
|
{
|
||||||
const char* s;
|
// save the atom
|
||||||
char* str = NULL;
|
assert((atom & ~0xff) == 0);
|
||||||
|
putSubtoken(static_cast<char>(atom));
|
||||||
|
|
||||||
if (token > PpAtomMaxSingle)
|
// save the backing name string
|
||||||
lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
|
if (SaveName(atom)) {
|
||||||
else
|
const char* s = ppToken->name;
|
||||||
lAddByte(pTok, (unsigned char)(token & 0x7f));
|
|
||||||
|
|
||||||
switch (token) {
|
|
||||||
case PpAtomIdentifier:
|
|
||||||
case PpAtomConstString:
|
|
||||||
s = ppToken->name;
|
|
||||||
while (*s)
|
while (*s)
|
||||||
lAddByte(pTok, (unsigned char) *s++);
|
putSubtoken(*s++);
|
||||||
lAddByte(pTok, 0);
|
putSubtoken(0);
|
||||||
break;
|
|
||||||
case PpAtomConstInt:
|
|
||||||
case PpAtomConstUint:
|
|
||||||
case PpAtomConstInt64:
|
|
||||||
case PpAtomConstUint64:
|
|
||||||
case PpAtomConstFloat:
|
|
||||||
case PpAtomConstDouble:
|
|
||||||
str = ppToken->name;
|
|
||||||
while (*str) {
|
|
||||||
lAddByte(pTok, (unsigned char) *str);
|
|
||||||
str++;
|
|
||||||
}
|
}
|
||||||
lAddByte(pTok, 0);
|
|
||||||
break;
|
// save the numeric value
|
||||||
default:
|
if (SaveValue(atom)) {
|
||||||
break;
|
const char* n = reinterpret_cast<const char*>(&ppToken->i64val);
|
||||||
|
for (int i = 0; i < sizeof(ppToken->i64val); ++i)
|
||||||
|
putSubtoken(*n++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Read the next token from a token stream.
|
||||||
* Reset a token stream in preperation for reading.
|
// (Not the source stream, but a stream used to hold a tokenized macro).
|
||||||
*/
|
int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
|
||||||
void TPpContext::RewindTokenStream(TokenStream *pTok)
|
|
||||||
{
|
{
|
||||||
pTok->current = 0;
|
// get the atom
|
||||||
}
|
int atom = getSubtoken();
|
||||||
|
if (atom == EndOfInput)
|
||||||
|
return atom;
|
||||||
|
|
||||||
/*
|
// init the token
|
||||||
* Read the next token from a token stream (not the source stream, but stream used to hold a tokenized macro).
|
ppToken->clear();
|
||||||
*/
|
|
||||||
int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
|
|
||||||
{
|
|
||||||
char* tokenText = ppToken->name;
|
|
||||||
int ltoken, len;
|
|
||||||
int ch;
|
|
||||||
|
|
||||||
ltoken = lReadByte(pTok);
|
|
||||||
ppToken->loc = parseContext.getCurrentLoc();
|
ppToken->loc = parseContext.getCurrentLoc();
|
||||||
if (ltoken > 127)
|
|
||||||
ltoken += 128;
|
// get the backing name string
|
||||||
switch (ltoken) {
|
if (SaveName(atom)) {
|
||||||
case '#':
|
int ch = getSubtoken();
|
||||||
if (lReadByte(pTok) == '#') {
|
int len = 0;
|
||||||
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
|
|
||||||
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
|
|
||||||
parseContext.error(ppToken->loc, "token pasting not implemented (internal error)", "##", "");
|
|
||||||
//return PpAtomPaste;
|
|
||||||
return ReadToken(pTok, ppToken);
|
|
||||||
} else
|
|
||||||
lUnreadByte(pTok);
|
|
||||||
break;
|
|
||||||
case PpAtomConstString:
|
|
||||||
case PpAtomIdentifier:
|
|
||||||
case PpAtomConstFloat:
|
|
||||||
case PpAtomConstDouble:
|
|
||||||
case PpAtomConstInt:
|
|
||||||
case PpAtomConstUint:
|
|
||||||
case PpAtomConstInt64:
|
|
||||||
case PpAtomConstUint64:
|
|
||||||
len = 0;
|
|
||||||
ch = lReadByte(pTok);
|
|
||||||
while (ch != 0 && ch != EndOfInput) {
|
while (ch != 0 && ch != EndOfInput) {
|
||||||
if (len < MaxTokenLength) {
|
if (len < MaxTokenLength) {
|
||||||
tokenText[len] = (char)ch;
|
ppToken->name[len] = (char)ch;
|
||||||
len++;
|
len++;
|
||||||
ch = lReadByte(pTok);
|
ch = getSubtoken();
|
||||||
} else {
|
} else {
|
||||||
parseContext.error(ppToken->loc, "token too long", "", "");
|
parseContext.error(ppToken->loc, "token too long", "", "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tokenText[len] = 0;
|
ppToken->name[len] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
switch (ltoken) {
|
// Check for ##, unless the current # is the last character
|
||||||
case PpAtomIdentifier:
|
if (atom == '#') {
|
||||||
ppToken->atom = LookUpAddString(tokenText);
|
if (current < data.size()) {
|
||||||
break;
|
if (getSubtoken() == '#') {
|
||||||
case PpAtomConstString:
|
parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
|
||||||
break;
|
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
|
||||||
case PpAtomConstFloat:
|
atom = PpAtomPaste;
|
||||||
case PpAtomConstDouble:
|
|
||||||
ppToken->dval = atof(ppToken->name);
|
|
||||||
break;
|
|
||||||
case PpAtomConstInt:
|
|
||||||
case PpAtomConstUint:
|
|
||||||
if (len > 0 && tokenText[0] == '0') {
|
|
||||||
if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
|
|
||||||
ppToken->ival = strtol(ppToken->name, 0, 16);
|
|
||||||
else
|
|
||||||
ppToken->ival = strtol(ppToken->name, 0, 8);
|
|
||||||
} else
|
} else
|
||||||
ppToken->ival = atoi(ppToken->name);
|
ungetSubtoken();
|
||||||
break;
|
|
||||||
case PpAtomConstInt64:
|
|
||||||
case PpAtomConstUint64:
|
|
||||||
if (len > 0 && tokenText[0] == '0') {
|
|
||||||
if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
|
|
||||||
ppToken->i64val = strtoll(ppToken->name, nullptr, 16);
|
|
||||||
else
|
|
||||||
ppToken->i64val = strtoll(ppToken->name, nullptr, 8);
|
|
||||||
} else
|
|
||||||
ppToken->i64val = atoll(ppToken->name);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ltoken;
|
// get the numeric value
|
||||||
|
if (SaveValue(atom)) {
|
||||||
|
char* n = reinterpret_cast<char*>(&ppToken->i64val);
|
||||||
|
for (int i = 0; i < sizeof(ppToken->i64val); ++i)
|
||||||
|
*n++ = getSubtoken();
|
||||||
|
}
|
||||||
|
|
||||||
|
return atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPpContext::tTokenInput::scan(TPpToken* ppToken)
|
// We are pasting if
|
||||||
|
// 1. we are preceding a pasting operator within this stream
|
||||||
|
// or
|
||||||
|
// 2. the entire macro is preceding a pasting operator (lastTokenPastes)
|
||||||
|
// and we are also on the last token
|
||||||
|
bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
|
||||||
{
|
{
|
||||||
return pp->ReadToken(tokens, ppToken);
|
// 1. preceding ##?
|
||||||
|
|
||||||
|
size_t savePos = current;
|
||||||
|
int subtoken;
|
||||||
|
// skip white space
|
||||||
|
do {
|
||||||
|
subtoken = getSubtoken();
|
||||||
|
} while (subtoken == ' ');
|
||||||
|
current = savePos;
|
||||||
|
if (subtoken == PpAtomPaste)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// 2. last token and we've been told after this there will be a ##
|
||||||
|
|
||||||
|
if (! lastTokenPastes)
|
||||||
|
return false;
|
||||||
|
// Getting here means the last token will be pasted, after this
|
||||||
|
|
||||||
|
// Are we at the last non-whitespace token?
|
||||||
|
savePos = current;
|
||||||
|
bool moreTokens = false;
|
||||||
|
do {
|
||||||
|
subtoken = getSubtoken();
|
||||||
|
if (subtoken == EndOfInput)
|
||||||
|
break;
|
||||||
|
if (subtoken != ' ') {
|
||||||
|
moreTokens = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
current = savePos;
|
||||||
|
|
||||||
|
return !moreTokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TPpContext::pushTokenStreamInput(TokenStream* ts)
|
// See if the next non-white-space tokens are two consecutive #
|
||||||
|
bool TPpContext::TokenStream::peekUntokenizedPasting()
|
||||||
{
|
{
|
||||||
pushInput(new tTokenInput(this, ts));
|
// don't return early, have to restore this
|
||||||
RewindTokenStream(ts);
|
size_t savePos = current;
|
||||||
|
|
||||||
|
// skip white-space
|
||||||
|
int subtoken;
|
||||||
|
do {
|
||||||
|
subtoken = getSubtoken();
|
||||||
|
} while (subtoken == ' ');
|
||||||
|
|
||||||
|
// check for ##
|
||||||
|
bool pasting = false;
|
||||||
|
if (subtoken == '#') {
|
||||||
|
subtoken = getSubtoken();
|
||||||
|
if (subtoken == '#')
|
||||||
|
pasting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = savePos;
|
||||||
|
|
||||||
|
return pasting;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting)
|
||||||
|
{
|
||||||
|
pushInput(new tTokenInput(this, &ts, prepasting));
|
||||||
|
ts.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPpContext::tUngotTokenInput::scan(TPpToken* ppToken)
|
int TPpContext::tUngotTokenInput::scan(TPpToken* ppToken)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
//
|
//
|
||||||
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||||
//All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
//Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
//modification, are permitted provided that the following conditions
|
// modification, are permitted provided that the following conditions
|
||||||
//are met:
|
// are met:
|
||||||
//
|
//
|
||||||
// Redistributions of source code must retain the above copyright
|
// Redistributions of source code must retain the above copyright
|
||||||
// notice, this list of conditions and the following disclaimer.
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
@ -18,18 +18,18 @@
|
||||||
// contributors may be used to endorse or promote products derived
|
// contributors may be used to endorse or promote products derived
|
||||||
// from this software without specific prior written permission.
|
// from this software without specific prior written permission.
|
||||||
//
|
//
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
/****************************************************************************\
|
/****************************************************************************\
|
||||||
Copyright (c) 2002, NVIDIA Corporation.
|
Copyright (c) 2002, NVIDIA Corporation.
|
||||||
|
@ -82,15 +82,19 @@ namespace glslang {
|
||||||
|
|
||||||
// Multi-character tokens
|
// Multi-character tokens
|
||||||
enum EFixedAtoms {
|
enum EFixedAtoms {
|
||||||
PpAtomMaxSingle = 256, // single character tokens get their own char value as their token, skip them
|
// single character tokens get their own char value as their token; start here for multi-character tokens
|
||||||
|
PpAtomMaxSingle = 127,
|
||||||
|
|
||||||
|
// replace bad character tokens with this, to avoid accidental aliasing with the below
|
||||||
|
PpAtomBadToken,
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
PpAtomAdd,
|
PPAtomAddAssign,
|
||||||
PpAtomSub,
|
PPAtomSubAssign,
|
||||||
PpAtomMul,
|
PPAtomMulAssign,
|
||||||
PpAtomDiv,
|
PPAtomDivAssign,
|
||||||
PpAtomMod,
|
PPAtomModAssign,
|
||||||
|
|
||||||
PpAtomRight,
|
PpAtomRight,
|
||||||
PpAtomLeft,
|
PpAtomLeft,
|
||||||
|
@ -113,6 +117,8 @@ enum EFixedAtoms {
|
||||||
PpAtomDecrement,
|
PpAtomDecrement,
|
||||||
PpAtomIncrement,
|
PpAtomIncrement,
|
||||||
|
|
||||||
|
PpAtomColonColon,
|
||||||
|
|
||||||
PpAtomPaste,
|
PpAtomPaste,
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
@ -121,17 +127,19 @@ enum EFixedAtoms {
|
||||||
PpAtomConstUint,
|
PpAtomConstUint,
|
||||||
PpAtomConstInt64,
|
PpAtomConstInt64,
|
||||||
PpAtomConstUint64,
|
PpAtomConstUint64,
|
||||||
|
PpAtomConstInt16,
|
||||||
|
PpAtomConstUint16,
|
||||||
PpAtomConstFloat,
|
PpAtomConstFloat,
|
||||||
PpAtomConstDouble,
|
PpAtomConstDouble,
|
||||||
|
PpAtomConstFloat16,
|
||||||
PpAtomConstString,
|
PpAtomConstString,
|
||||||
|
|
||||||
// Indentifiers
|
// Identifiers
|
||||||
PpAtomIdentifier,
|
PpAtomIdentifier,
|
||||||
|
|
||||||
// preprocessor "keywords"
|
// preprocessor "keywords"
|
||||||
|
|
||||||
PpAtomDefine,
|
PpAtomDefine,
|
||||||
PpAtomDefined,
|
|
||||||
PpAtomUndef,
|
PpAtomUndef,
|
||||||
|
|
||||||
PpAtomIf,
|
PpAtomIf,
|
||||||
|
|
|
@ -90,6 +90,7 @@ bool isDereferenceOperation(glslang::TOperator op)
|
||||||
case glslang::EOpIndexDirectStruct:
|
case glslang::EOpIndexDirectStruct:
|
||||||
case glslang::EOpIndexIndirect:
|
case glslang::EOpIndexIndirect:
|
||||||
case glslang::EOpVectorSwizzle:
|
case glslang::EOpVectorSwizzle:
|
||||||
|
case glslang::EOpMatrixSwizzle:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -272,9 +273,9 @@ TSymbolDefinitionCollectingTraverser::TSymbolDefinitionCollectingTraverser(
|
||||||
ObjectAccesschainSet* precise_objects,
|
ObjectAccesschainSet* precise_objects,
|
||||||
std::unordered_set<glslang::TIntermBranch*>* precise_return_nodes)
|
std::unordered_set<glslang::TIntermBranch*>* precise_return_nodes)
|
||||||
: TIntermTraverser(true, false, false), symbol_definition_mapping_(*symbol_definition_mapping),
|
: TIntermTraverser(true, false, false), symbol_definition_mapping_(*symbol_definition_mapping),
|
||||||
precise_objects_(*precise_objects), current_object_(),
|
precise_objects_(*precise_objects), precise_return_nodes_(*precise_return_nodes),
|
||||||
accesschain_mapping_(*accesschain_mapping), current_function_definition_node_(nullptr),
|
current_object_(), accesschain_mapping_(*accesschain_mapping),
|
||||||
precise_return_nodes_(*precise_return_nodes) {}
|
current_function_definition_node_(nullptr) {}
|
||||||
|
|
||||||
// Visits a symbol node, set the current_object_ to the
|
// Visits a symbol node, set the current_object_ to the
|
||||||
// current node symbol ID, and record a mapping from this node to the current
|
// current node symbol ID, and record a mapping from this node to the current
|
||||||
|
@ -616,9 +617,9 @@ class TNoContractionPropagator : public glslang::TIntermTraverser {
|
||||||
public:
|
public:
|
||||||
TNoContractionPropagator(ObjectAccesschainSet* precise_objects,
|
TNoContractionPropagator(ObjectAccesschainSet* precise_objects,
|
||||||
const AccessChainMapping& accesschain_mapping)
|
const AccessChainMapping& accesschain_mapping)
|
||||||
: TIntermTraverser(true, false, false), remained_accesschain_(),
|
: TIntermTraverser(true, false, false),
|
||||||
precise_objects_(*precise_objects), accesschain_mapping_(accesschain_mapping),
|
precise_objects_(*precise_objects), added_precise_object_ids_(),
|
||||||
added_precise_object_ids_() {}
|
remained_accesschain_(), accesschain_mapping_(accesschain_mapping) {}
|
||||||
|
|
||||||
// Propagates 'precise' in the right nodes of a given assignment node with
|
// Propagates 'precise' in the right nodes of a given assignment node with
|
||||||
// access chain record from the assignee node to a 'precise' object it
|
// access chain record from the assignee node to a 'precise' object it
|
||||||
|
@ -670,7 +671,7 @@ protected:
|
||||||
// Gets the struct dereference index that leads to 'precise' object.
|
// Gets the struct dereference index that leads to 'precise' object.
|
||||||
ObjectAccessChain precise_accesschain_index_str =
|
ObjectAccessChain precise_accesschain_index_str =
|
||||||
getFrontElement(remained_accesschain_);
|
getFrontElement(remained_accesschain_);
|
||||||
unsigned precise_accesschain_index = strtoul(precise_accesschain_index_str.c_str(), nullptr, 10);
|
unsigned precise_accesschain_index = (unsigned)strtoul(precise_accesschain_index_str.c_str(), nullptr, 10);
|
||||||
// Gets the node pointed by the access chain index extracted before.
|
// Gets the node pointed by the access chain index extracted before.
|
||||||
glslang::TIntermTyped* potential_precise_node =
|
glslang::TIntermTyped* potential_precise_node =
|
||||||
node->getSequence()[precise_accesschain_index]->getAsTyped();
|
node->getSequence()[precise_accesschain_index]->getAsTyped();
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue