Externals: Update glslang to upstream commit 32d3ec3

This commit is contained in:
Stenzek 2018-06-02 07:26:43 +00:00
parent 160d16f1b3
commit bc96557ec4
149 changed files with 47830 additions and 13886 deletions

View File

@ -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

17
Externals/glslang/.gitattributes vendored Normal file
View File

@ -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

10
Externals/glslang/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
*.o
*.a
*.so
*.exe
tags
TAGS
build/
Test/localResults/
External/googletest
External/spirv-tools

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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)

108
Externals/glslang/SPIRV/GLSL.ext.AMD.h vendored Normal file
View File

@ -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

37
Externals/glslang/SPIRV/GLSL.ext.EXT.h vendored Normal file
View File

@ -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

42
Externals/glslang/SPIRV/GLSL.ext.KHR.h vendored Normal file
View File

@ -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

57
Externals/glslang/SPIRV/GLSL.ext.NV.h vendored Normal file
View File

@ -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

View File

@ -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);
} }

View File

@ -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_;
}; };
} }

View File

@ -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

View File

@ -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

View File

@ -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

81
Externals/glslang/SPIRV/bitutils.h vendored Normal file
View File

@ -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_

210
Externals/glslang/SPIRV/disassemble.cpp vendored Normal file → Executable file
View File

@ -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);

View File

@ -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

View File

@ -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[];

1078
Externals/glslang/SPIRV/hex_float.h vendored Normal file

File diff suppressed because it is too large Load Diff

196
Externals/glslang/SPIRV/spirv.hpp vendored Executable file → Normal file
View File

@ -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,
}; };

View File

@ -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);

28
Externals/glslang/StandAlone/CMakeLists.txt vendored Normal file → Executable file
View File

@ -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)

View File

@ -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);
}
};

View File

@ -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

View File

@ -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;
}; };

View File

@ -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;

View File

@ -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" />

View File

@ -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>

40
Externals/glslang/glslang/CMakeLists.txt vendored Normal file → Executable file
View File

@ -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)

View File

@ -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"

View File

@ -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.
// //
// //

View 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.
// //
#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_

View File

@ -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;

View File

@ -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); }

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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

683
Externals/glslang/glslang/Include/intermediate.h vendored Normal file → Executable file
View 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,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

View File

@ -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"

View 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,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;
} }

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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.
// //

View File

@ -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"

View File

@ -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*);

View File

@ -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;

View File

@ -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) {

View File

@ -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

View 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,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) {

View File

@ -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
View 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, "");
} }

131
Externals/glslang/glslang/MachineIndependent/Versions.h vendored Normal file → Executable file
View 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.
// //
#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 };

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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
View 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);
} }

View File

@ -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;
// Dont take into account the outer-most array if the stages
// 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

View File

@ -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

View File

@ -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.
// //
// //

View File

@ -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
View 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

View File

@ -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;

View File

@ -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&);
}; };

View 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.
@ -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;
} }

View 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,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;
} }

View 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
View 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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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)

View File

@ -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,

View File

@ -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