Merge pull request #6038 from stenzek/update-glslang

Externals: Update glslang to upstream commit 32d3ec3
This commit is contained in:
Mat M 2018-06-02 03:54:04 -04:00 committed by GitHub
commit d67de4cc15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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,12 +7,15 @@ 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:
- GLSLANG_BUILD_TYPE=Release global:
- GLSLANG_BUILD_TYPE=Debug - 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=Debug
compiler: compiler:
- clang - clang
@ -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")
include(ChooseMSVCCRT.cmake) if(MSVC)
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,34 +1,43 @@
# 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)
message(STATUS "Google Mock already configured - use it") if(TARGET gmock)
elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest) message(STATUS "Google Mock already configured - use it")
# We need to make sure Google Test does not mess up with the elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
# global CRT settings on Windows. # We need to make sure Google Test does not mess up with the
if(WIN32) # global CRT settings on Windows.
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) if(WIN32)
endif(WIN32) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory(googletest) endif(WIN32)
set(GTEST_TARGETS add_subdirectory(googletest)
gtest set(GTEST_TARGETS
gtest_main gtest
gmock gtest_main
gmock_main gmock
) 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()
mark_as_advanced(gmock_build_tests mark_as_advanced(gmock_build_tests
BUILD_GMOCK BUILD_GMOCK
BUILD_GTEST BUILD_GTEST
BUILD_SHARED_LIBS BUILD_SHARED_LIBS
gtest_build_samples gtest_build_samples
gtest_build_tests gtest_build_tests
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"
@ -103,10 +103,10 @@ namespace spv {
switch (opCode) { switch (opCode) {
case spv::OpTypeVector: // fall through case spv::OpTypeVector: // fall through
case spv::OpTypeMatrix: // ... case spv::OpTypeMatrix: // ...
case spv::OpTypeSampler: // ... case spv::OpTypeSampler: // ...
case spv::OpTypeArray: // ... case spv::OpTypeArray: // ...
case spv::OpTypeRuntimeArray: // ... case spv::OpTypeRuntimeArray: // ...
case spv::OpTypePipe: return range_t(2, 3); case spv::OpTypePipe: return range_t(2, 3);
case spv::OpTypeStruct: // fall through case spv::OpTypeStruct: // fall through
case spv::OpTypeFunction: return range_t(2, maxCount); case spv::OpTypeFunction: return range_t(2, maxCount);
@ -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
} }
@ -817,7 +991,7 @@ namespace spv {
}, },
// If local var id used anywhere else, don't eliminate // If local var id used anywhere else, don't eliminate
[&](spv::Id& id) { [&](spv::Id& id) {
if (fnLocalVars.count(id) > 0) { if (fnLocalVars.count(id) > 0) {
fnLocalVars.erase(id); fnLocalVars.erase(id);
idMap.erase(id); idMap.erase(id);
@ -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);
stripInst(start); if (opCode == spv::OpDecorate || opCode == spv::OpName)
} id = asId(start+1);
if (id != spv::NoResult && varUseCount[id] == 1)
stripInst(start);
return true; return true;
}, },
op_fn_nop); op_fn_nop);
@ -966,28 +1158,37 @@ namespace spv {
std::unordered_map<spv::Id, int> typeUseCount; std::unordered_map<spv::Id, int> typeUseCount;
// Count total type usage // This is not the most efficient algorithm, but this is an offline tool, and
process(inst_fn_nop, // it's easy to write this way. Can be improved opportunistically if needed.
[&](spv::Id& id) { if (isType[id]) ++typeUseCount[id]; } bool changed = true;
); while (changed) {
changed = false;
strip();
typeUseCount.clear();
// Remove types from deleted code // Count total type usage
for (const auto& fn : fnPosDCE)
process(inst_fn_nop, process(inst_fn_nop,
[&](spv::Id& id) { if (isType[id]) --typeUseCount[id]; }, [&](spv::Id& id) { if (isType[id]) ++typeUseCount[id]; }
fn.second.first, fn.second.second); );
// Remove single reference types if (errorLatch)
for (const auto typeStart : typeConstPos) { return;
const spv::Id typeId = asTypeConstId(typeStart);
if (typeUseCount[typeId] == 1) { // Remove single reference types
--typeUseCount[typeId]; for (const auto typeStart : typeConstPos) {
stripInst(typeStart); const spv::Id typeId = asTypeConstId(typeStart);
if (typeUseCount[typeId] == 1) {
changed = true;
--typeUseCount[typeId];
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,12 +1366,17 @@ 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)
return;
if (isOldIdUnmapped(resId)) {
localId(resId, nextUnusedId(hashval % softTypeIdLimit + firstMappedID)); 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)
@ -1206,25 +1413,56 @@ namespace spv {
// Set up opcode tables from SpvDoc // Set up opcode tables from SpvDoc
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 & DCE_TYPES) dceTypes();
if (options & MAP_TYPES) mapTypeConst();
if (options & MAP_NAMES) mapNames();
if (options & MAP_FUNCS) mapFnBodies();
mapRemainder(); // map any unmapped IDs if (options & OPT_FWD_LS) forwardLoadStores();
applyMap(); // Now remap each shader to the new IDs we've come up with if (errorLatch) return;
strip(); // strip out data we decided to eliminate
if (options & DCE_FUNCS) dceFuncs();
if (errorLatch) return;
if (options & DCE_VARS) dceVars();
if (errorLatch) return;
if (options & DCE_TYPES) dceTypes();
if (errorLatch) return;
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,8 +112,11 @@ 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,17 +164,22 @@ 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;
// handle error // Maps and ID to the size of its base type, if known.
void error(const std::string& txt) const { errorHandler(txt); } typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;
// handle error
void error(const std::string& txt) const { errorLatch = true; errorHandler(txt); }
bool isConstOp(spv::Op opCode) const;
bool isTypeOp(spv::Op opCode) const;
bool isStripOp(spv::Op opCode) const;
bool isFlowCtrl(spv::Op opCode) const;
range_t literalRange(spv::Op opCode) const;
range_t typeRange(spv::Op opCode) const;
range_t constRange(spv::Op opCode) const;
unsigned typeSizeInWords(spv::Id id) const;
unsigned idTypeSizeInWords(spv::Id id) const;
bool isConstOp(spv::Op opCode) const;
bool isTypeOp(spv::Op opCode) const;
bool isStripOp(spv::Op opCode) const;
bool isFlowCtrl(spv::Op opCode) const;
range_t literalRange(spv::Op opCode) const;
range_t typeRange(spv::Op opCode) const;
range_t constRange(spv::Op opCode) 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]; }
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); } spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
@ -177,10 +187,10 @@ 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); }
// Header access & set methods // Header access & set methods
spirword_t magic() const { return spv[0]; } // return magic number spirword_t magic() const { return spv[0]; } // return magic number
@ -233,9 +243,10 @@ 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
namemap_t nameMap; // ID names from OpName namemap_t nameMap; // ID names from OpName
@ -258,14 +269,14 @@ 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
spv::Id entryPoint; // module entry point spv::Id entryPoint; // module entry point
@ -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.
@ -297,7 +336,7 @@ public:
// Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'. // Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'.
// The type of the created vector is a vector of components of the same type as the scalar. // The type of the created vector is a vector of components of the same type as the scalar.
// //
// Note: One of the arguments will change, with the result coming back that way rather than // Note: One of the arguments will change, with the result coming back that way rather than
// through the return value. // through the return value.
void promoteScalar(Decoration precision, Id& left, Id& right); void promoteScalar(Decoration precision, Id& left, Id& right);
@ -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)
{ {
accessChain.component = component; if (accessChain.swizzle.size() != 1) {
if (accessChain.preSwizzleBaseType == NoType) accessChain.component = component;
accessChain.preSwizzleBaseType = preSwizzleBaseType; if (accessChain.preSwizzleBaseType == NoType)
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_

214
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 >= bound)
Kill(out, "Bad <id>");
if (id != 0) { 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)
Kill(out, "Bad <id>");
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>
@ -149,7 +151,7 @@ enum OperandClass {
OperandMemorySemantics, OperandMemorySemantics,
OperandMemoryAccess, OperandMemoryAccess,
OperandScope, OperandScope,
OperandGroupOperation, OperandGroupOperation,
OperandKernelEnqueueFlags, OperandKernelEnqueueFlags,
OperandKernelProfilingInfo, OperandKernelProfilingInfo,
OperandCapability, OperandCapability,
@ -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,26 +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.
// SPIRV-IR // SPIRV-IR
// //
// Simple in-memory representation (IR) of SPIRV. Just for holding // Simple in-memory representation (IR) of SPIRV. Just for holding
// Each function's CFG of blocks. Has this hierarchy: // Each function's CFG of blocks. Has this hierarchy:
// - Module, which is a list of // - Module, which is a list of
// - Function, which is a list of // - Function, which is a list of
// - Block, which is a list of // - Block, which is a list of
// - Instruction // - Instruction
// //
@ -65,12 +65,17 @@ const Id NoResult = 0;
const Id NoType = 0; const Id NoType = 0;
const Decoration NoPrecision = DecorationMax; const Decoration NoPrecision = DecorationMax;
const MemorySemanticsMask MemorySemanticsAllMemory =
(MemorySemanticsMask)(MemorySemanticsSequentiallyConsistentMask | #ifdef __GNUC__
MemorySemanticsUniformMemoryMask | # define POTENTIALLY_UNUSED __attribute__((unused))
MemorySemanticsSubgroupMemoryMask | #else
# define POTENTIALLY_UNUSED
#endif
POTENTIALLY_UNUSED
const MemorySemanticsMask MemorySemanticsAllMemory =
(MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
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;
}; };
@ -229,7 +231,7 @@ protected:
std::vector<std::unique_ptr<Instruction> > localVariables; std::vector<std::unique_ptr<Instruction> > localVariables;
Function& parent; Function& parent;
// track whether this block is known to be uncreachable (not necessarily // track whether this block is known to be uncreachable (not necessarily
// true for all unreachable blocks, but should be set at least // true for all unreachable blocks, but should be set at least
// for the extraneous ones introduced by the builder). // for the extraneous ones introduced by the builder).
bool unreachable; bool unreachable;
@ -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);

30
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,23 +59,18 @@ 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>
@ -143,8 +143,8 @@ namespace {
<< " [--map (all|types|names|funcs)]" << " [--map (all|types|names|funcs)]"
<< " [--dce (all|types|funcs)]" << " [--dce (all|types|funcs)]"
<< " [--opt (all|loadstore)]" << " [--opt (all|loadstore)]"
<< " [--strip-all | --strip all | -s]" << " [--strip-all | --strip all | -s]"
<< " [--do-everything]" << " [--do-everything]"
<< " --input | -i file1 [file2...] --output|-o DESTDIR" << " --input | -i file1 [file2...] --output|-o DESTDIR"
<< std::endl; << std::endl;
@ -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" />
@ -134,4 +125,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

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>
@ -311,4 +281,4 @@
<Filter>glslang\MachineIndependant</Filter> <Filter>glslang\MachineIndependant</Filter>
</None> </None>
</ItemGroup> </ItemGroup>
</Project> </Project>

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.
// //
// //
@ -46,7 +46,7 @@ class TGenericLinker : public TLinker {
public: public:
TGenericLinker(EShExecutable e, int dOptions) : TLinker(e, infoSink), debugOptions(dOptions) { } TGenericLinker(EShExecutable e, int dOptions) : TLinker(e, infoSink), debugOptions(dOptions) { }
bool link(TCompilerList&, TUniformMap*) { return true; } bool link(TCompilerList&, TUniformMap*) { return true; }
void getAttributeBindings(ShBindingTable const **) const { } void getAttributeBindings(ShBindingTable const **) const { }
TInfoSink infoSink; TInfoSink infoSink;
int debugOptions; int debugOptions;
}; };

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
}; };
@ -77,7 +87,7 @@ enum TStorageQualifier {
EvqUniform, // read only, shared with app EvqUniform, // read only, shared with app
EvqBuffer, // read/write, shared with app EvqBuffer, // read/write, shared with app
EvqShared, // compute shader's read/write 'shared' qualifier EvqShared, // compute shader's read/write 'shared' qualifier
// parameters // parameters
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter
@ -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,16 +201,54 @@ 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
}; };
// These will show up in error messages // These will show up in error messages
__inline const char* GetStorageQualifierString(TStorageQualifier q) __inline const char* GetStorageQualifierString(TStorageQualifier q)
{ {
switch (q) { switch (q) {
case EvqTemporary: return "temp"; break; case EvqTemporary: return "temp"; break;
@ -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
return _strtoi64(str, endptr, base); #define snprintf sprintf_s
} #endif
inline long long int atoll (const char* str) #define safe_vsprintf(buf,max,format,args) vsnprintf_s((buf), (max), (max), (format), (args))
{ #elif defined (solaris)
return strtoll(str, NULL, 10); #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);
}
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);
}
#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"
@ -99,11 +111,11 @@ inline long long int atoll (const char* str)
// //
#define POOL_ALLOCATOR_NEW_DELETE(A) \ #define POOL_ALLOCATOR_NEW_DELETE(A) \
void* operator new(size_t s) { return (A).allocate(s); } \ void* operator new(size_t s) { return (A).allocate(s); } \
void* operator new(size_t, void *_Where) { return (_Where); } \ void* operator new(size_t, void *_Where) { return (_Where); } \
void operator delete(void*) { } \ void operator delete(void*) { } \
void operator delete(void *, void *) { } \ void operator delete(void *, void *) { } \
void* operator new[](size_t s) { return (A).allocate(s); } \ void* operator new[](size_t s) { return (A).allocate(s); } \
void* operator new[](size_t, void *_Where) { return (_Where); } \ void* operator new[](size_t, void *_Where) { return (_Where); } \
void operator delete[](void*) { } \ void operator delete[](void*) { } \
void operator delete[](void *, void *) { } void operator delete[](void *, void *) { }
@ -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;
} }
@ -174,7 +186,7 @@ public:
template <class T> class TList : public std::list<T, pool_allocator<T> > { template <class T> class TList : public std::list<T, pool_allocator<T> > {
}; };
template <class K, class D, class CMP = std::less<K> > template <class K, class D, class CMP = std::less<K> >
class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<K const, D> > > { class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<K const, D> > > {
}; };
@ -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
_itoa_s(i, text, sizeof(text), base);
#if defined _MSC_VER || defined MINGW_HAS_SECURE_API return text;
_itoa_s(i, text, sizeof(text), base); }
#else #else
// we assume base 10 for all cases inline const TString String(const int i, const int /*base*/ = 10)
snprintf(text, sizeof(text), "%d", i); {
#endif char text[16]; // 32 bit ints are at most 10 digits in base 10
// we assume base 10 for all cases
snprintf(text, sizeof(text), "%d", i);
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,15 +49,39 @@ 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;
type = EbtInt; type = EbtInt;
} }
void setUConst(unsigned int u) void setUConst(unsigned int u)
{ {
uConst = u; uConst = u;
type = EbtUint; type = EbtUint;
} }
@ -71,22 +99,65 @@ public:
void setDConst(double d) void setDConst(double d)
{ {
dConst = d; dConst = d;
type = EbtDouble; type = EbtDouble;
} }
void setBConst(bool b) void setBConst(bool b)
{ {
bConst = b; bConst = b;
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);
@ -215,9 +326,29 @@ public:
} }
bool operator>(const TConstUnion& constant) const bool operator>(const TConstUnion& constant) const
{ {
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;
@ -250,9 +381,29 @@ public:
} }
bool operator<(const TConstUnion& constant) const bool operator<(const TConstUnion& constant) const
{ {
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;
@ -285,13 +436,17 @@ public:
} }
TConstUnion operator+(const TConstUnion& constant) const TConstUnion operator+(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break;
case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break;
case EbtUint: returnValue.setUConst(uConst + constant.uConst); break; case EbtInt: returnValue.setIConst(iConst + constant.iConst); 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 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;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
@ -301,13 +456,17 @@ public:
} }
TConstUnion operator-(const TConstUnion& constant) const TConstUnion operator-(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break;
case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break;
case EbtUint: returnValue.setUConst(uConst - constant.uConst); break; case EbtInt: returnValue.setIConst(iConst - constant.iConst); 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 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;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
@ -317,15 +476,19 @@ public:
} }
TConstUnion operator*(const TConstUnion& constant) const TConstUnion operator*(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break;
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break;
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; case EbtInt: returnValue.setIConst(iConst * constant.iConst); 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 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;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
@ -333,13 +496,17 @@ public:
} }
TConstUnion operator%(const TConstUnion& constant) const TConstUnion operator%(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break;
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break; case EbtInt: returnValue.setIConst(iConst % constant.iConst); 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 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");
} }
@ -348,11 +515,67 @@ public:
} }
TConstUnion operator>>(const TConstUnion& constant) const TConstUnion operator>>(const TConstUnion& constant) const
{ {
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;
@ -394,11 +629,67 @@ public:
} }
TConstUnion operator<<(const TConstUnion& constant) const TConstUnion operator<<(const TConstUnion& constant) const
{ {
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;
@ -415,8 +710,12 @@ public:
default: assert(false && "Default missing"); default: assert(false && "Default missing");
} }
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;
@ -440,12 +743,16 @@ public:
} }
TConstUnion operator&(const TConstUnion& constant) const TConstUnion operator&(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break;
case EbtUint: returnValue.setUConst(uConst & constant.uConst); 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 EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break; case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); 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");
@ -455,12 +762,16 @@ public:
} }
TConstUnion operator|(const TConstUnion& constant) const TConstUnion operator|(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break;
case EbtUint: returnValue.setUConst(uConst | constant.uConst); 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 EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break; case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); 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");
@ -470,12 +781,16 @@ public:
} }
TConstUnion operator^(const TConstUnion& constant) const TConstUnion operator^(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break;
case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); 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 EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break; case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); 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");
@ -485,11 +800,15 @@ public:
} }
TConstUnion operator~() const TConstUnion operator~() const
{ {
TConstUnion returnValue; TConstUnion returnValue;
switch (type) { switch (type) {
case EbtInt: returnValue.setIConst(~iConst); break; case EbtInt8: returnValue.setI8Const(~i8Const); break;
case EbtUint: returnValue.setUConst(~uConst); 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 EbtUint: returnValue.setUConst(~uConst); break;
case EbtInt64: returnValue.setI64Const(~i64Const); break; case EbtInt64: returnValue.setI64Const(~i64Const); break;
case EbtUint64: returnValue.setU64Const(~u64Const); break; case EbtUint64: returnValue.setU64Const(~u64Const); break;
default: assert(false && "Default missing"); default: assert(false && "Default missing");
@ -499,7 +818,7 @@ public:
} }
TConstUnion operator&&(const TConstUnion& constant) const TConstUnion operator&&(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
@ -511,7 +830,7 @@ public:
} }
TConstUnion operator||(const TConstUnion& constant) const TConstUnion operator||(const TConstUnion& constant) const
{ {
TConstUnion returnValue; TConstUnion returnValue;
assert(type == constant.type); assert(type == constant.type);
switch (type) { switch (type) {
@ -526,25 +845,30 @@ 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
// of C++ assuming it as an array of pointers to vectors. // of C++ assuming it as an array of pointers to vectors.
// //
// General usage is that the size is known up front, and it is // General usage is that the size is known up front, and it is
// created once with the proper size. // created once with the proper size.
// //
class TConstUnionArray { class TConstUnionArray {
@ -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,10 +74,9 @@ 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);
return *this; } return *this; }
TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; } TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; }
TInfoSinkBase& operator+(const TString& t) { append(t); return *this; } TInfoSinkBase& operator+(const TString& t) { append(t); return *this; }
@ -114,20 +113,20 @@ public:
append(s); append(s);
append("\n"); append("\n");
} }
void setOutputStream(int output = 4) void setOutputStream(int output = 4)
{ {
outputStream = output; outputStream = output;
} }
protected: protected:
void append(const char* s); void append(const char* s);
void append(int count, char c); void append(int count, char c);
void append(const TPersistString& t); void append(const TPersistString& t);
void append(const TString& t); void append(const TString& t);
void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2) void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)
sink.reserve(sink.capacity() + sink.capacity() / 2); } sink.reserve(sink.capacity() + sink.capacity() / 2); }
void appendToStream(const char* s); void appendToStream(const char* s);
TPersistString sink; TPersistString sink;

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_
@ -43,8 +43,8 @@
// //
// This header defines an allocator that can be used to efficiently // This header defines an allocator that can be used to efficiently
// allocate a large number of small requests for heap memory, with the // allocate a large number of small requests for heap memory, with the
// intention that they are not individually deallocated, but rather // intention that they are not individually deallocated, but rather
// collectively deallocated at one time. // collectively deallocated at one time.
// //
// This simultaneously // This simultaneously
@ -61,16 +61,16 @@
// 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.
// //
class TAllocation { class TAllocation {
public: public:
@ -87,7 +87,7 @@ public:
memset(postGuard(), guardBlockEndVal, guardBlockSize); memset(postGuard(), guardBlockEndVal, guardBlockSize);
# endif # endif
} }
void check() const { void check() const {
checkGuardBlock(preGuard(), guardBlockBeginVal, "before"); checkGuardBlock(preGuard(), guardBlockBeginVal, "before");
checkGuardBlock(postGuard(), guardBlockEndVal, "after"); checkGuardBlock(postGuard(), guardBlockEndVal, "after");
@ -100,7 +100,7 @@ public:
inline static size_t allocationSize(size_t size) { inline static size_t allocationSize(size_t size) {
return size + 2 * guardBlockSize + headerSize(); return size + 2 * guardBlockSize + headerSize();
} }
// Offset from surrounding buffer to get to user data buffer. // Offset from surrounding buffer to get to user data buffer.
inline static unsigned char* offsetAllocation(unsigned char* m) { inline static unsigned char* offsetAllocation(unsigned char* m) {
return m + guardBlockSize + headerSize(); return m + guardBlockSize + headerSize();
@ -123,16 +123,16 @@ private:
const static unsigned char userDataFill; const static unsigned char userDataFill;
const static size_t guardBlockSize; const static size_t guardBlockSize;
# ifdef GUARD_BLOCKS # ifdef GUARD_BLOCKS
inline static size_t headerSize() { return sizeof(TAllocation); } inline static size_t headerSize() { return sizeof(TAllocation); }
# else # else
inline static size_t headerSize() { return 0; } inline static size_t headerSize() { return 0; }
# endif # endif
}; };
// //
// There are several stacks. One is to track the pushing and popping // There are several stacks. One is to track the pushing and popping
// of the user, and not yet implemented. The others are simply a // of the user, and not yet implemented. The others are simply a
// repositories of free pages or used pages. // repositories of free pages or used pages.
// //
// Page stacks are linked together with a simple header at the beginning // Page stacks are linked together with a simple header at the beginning
@ -141,7 +141,7 @@ private:
// re-use. // re-use.
// //
// The "page size" used is not, nor must it match, the underlying OS // The "page size" used is not, nor must it match, the underlying OS
// page size. But, having it be about that size or equal to a set of // page size. But, having it be about that size or equal to a set of
// pages is likely most optimal. // pages is likely most optimal.
// //
class TPoolAllocator { class TPoolAllocator {
@ -185,7 +185,7 @@ public:
protected: protected:
friend struct tHeader; friend struct tHeader;
struct tHeader { struct tHeader {
tHeader(tHeader* nextPage, size_t pageCount) : tHeader(tHeader* nextPage, size_t pageCount) :
#ifdef GUARD_BLOCKS #ifdef GUARD_BLOCKS
@ -227,7 +227,7 @@ protected:
} }
size_t pageSize; // granularity of allocation from the OS size_t pageSize; // granularity of allocation from the OS
size_t alignment; // all returned allocations will be aligned at size_t alignment; // all returned allocations will be aligned at
// this granularity, which will be a power of 2 // this granularity, which will be a power of 2
size_t alignmentMask; size_t alignmentMask;
size_t headerSkip; // amount of memory to skip to make room for the size_t headerSkip; // amount of memory to skip to make room for the
@ -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
@ -278,7 +270,7 @@ public:
typedef T& reference; typedef T& reference;
typedef const T& const_reference; typedef const T& const_reference;
typedef T value_type; typedef T value_type;
template<class Other> template<class Other>
struct rebind { struct rebind {
typedef pool_allocator<Other> other; typedef pool_allocator<Other> other;
}; };
@ -292,15 +284,15 @@ public:
template<class Other> template<class Other>
pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { } pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
pointer allocate(size_type n) { pointer allocate(size_type n) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); } return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
pointer allocate(size_type n, const void*) { pointer allocate(size_type n, const void*) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); } return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
void deallocate(void*, size_type) { } void deallocate(void*, size_type) { }
void deallocate(pointer, size_type) { } void deallocate(pointer, size_type) { }
pointer _Charalloc(size_t n) { pointer _Charalloc(size_t n) {
return reinterpret_cast<pointer>(getAllocator().allocate(n)); } return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
void construct(pointer p, const T& val) { new ((void *)p) T(val); } void construct(pointer p, const T& val) { new ((void *)p) T(val); }

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_
@ -81,7 +81,7 @@ struct TBuiltInResource {
int maxComputeImageUniforms; int maxComputeImageUniforms;
int maxComputeAtomicCounters; int maxComputeAtomicCounters;
int maxComputeAtomicCounterBuffers; int maxComputeAtomicCounterBuffers;
int maxVaryingComponents; int maxVaryingComponents;
int maxVertexOutputComponents; int maxVertexOutputComponents;
int maxGeometryInputComponents; int maxGeometryInputComponents;
int maxGeometryOutputComponents; int maxGeometryOutputComponents;

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,8 +42,7 @@
// 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"
#include "InfoSink.h" #include "InfoSink.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;
}; };
// //
@ -73,7 +75,7 @@ public:
TUniformMap() { } TUniformMap() { }
virtual ~TUniformMap() { } virtual ~TUniformMap() { }
virtual TUniformMap* getAsUniformMap() { return this; } virtual TUniformMap* getAsUniformMap() { return this; }
virtual int getLocation(const char* name) = 0; virtual int getLocation(const char* name) = 0;
virtual TInfoSink& getInfoSink() { return infoSink; } virtual TInfoSink& getInfoSink() { return infoSink; }
TInfoSink infoSink; TInfoSink infoSink;
}; };
@ -95,7 +97,7 @@ public:
virtual TCompiler* getAsCompiler() { return this; } virtual TCompiler* getAsCompiler() { return this; }
virtual bool linkable() { return haveValidObjectCode; } virtual bool linkable() { return haveValidObjectCode; }
TInfoSink& infoSink; TInfoSink& infoSink;
protected: protected:
TCompiler& operator=(TCompiler&); TCompiler& operator=(TCompiler&);
@ -117,14 +119,14 @@ typedef glslang::TVector<TShHandleBase*> THandleList;
class TLinker : public TShHandleBase { class TLinker : public TShHandleBase {
public: public:
TLinker(EShExecutable e, TInfoSink& iSink) : TLinker(EShExecutable e, TInfoSink& iSink) :
infoSink(iSink), infoSink(iSink),
executable(e), executable(e),
haveReturnableObjectCode(false), haveReturnableObjectCode(false),
appAttributeBindings(0), appAttributeBindings(0),
fixedAttributeBindings(0), fixedAttributeBindings(0),
excludedAttributes(0), excludedAttributes(0),
excludedCount(0), excludedCount(0),
uniformBindings(0) { } uniformBindings(0) { }
virtual TLinker* getAsLinker() { return this; } virtual TLinker* getAsLinker() { return this; }
virtual ~TLinker() { } virtual ~TLinker() { }
@ -132,8 +134,8 @@ public:
virtual bool link(THandleList&) { return false; } virtual bool link(THandleList&) { return false; }
virtual void setAppAttributeBindings(const ShBindingTable* t) { appAttributeBindings = t; } virtual void setAppAttributeBindings(const ShBindingTable* t) { appAttributeBindings = t; }
virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; } virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; }
virtual void getAttributeBindings(ShBindingTable const **t) const = 0; virtual void getAttributeBindings(ShBindingTable const **t) const = 0;
virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; } virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; }
virtual ShBindingTable* getUniformBindings() const { return uniformBindings; } virtual ShBindingTable* getUniformBindings() const { return uniformBindings; }
virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here
virtual TInfoSink& getInfoSink() { return infoSink; } virtual TInfoSink& getInfoSink() { return infoSink; }
@ -145,9 +147,9 @@ protected:
const ShBindingTable* appAttributeBindings; const ShBindingTable* appAttributeBindings;
const ShBindingTable* fixedAttributeBindings; const ShBindingTable* fixedAttributeBindings;
const int* excludedAttributes; const int* excludedAttributes;
int excludedCount; int excludedCount;
ShBindingTable* uniformBindings; // created by the linker ShBindingTable* uniformBindings; // created by the linker
}; };
// //
@ -155,7 +157,7 @@ protected:
// and the machine dependent code. // and the machine dependent code.
// //
// The machine dependent code should derive from the classes // The machine dependent code should derive from the classes
// above. Then Construct*() and Delete*() will create and // above. Then Construct*() and Delete*() will create and
// destroy the machine dependent objects, which contain the // destroy the machine dependent objects, which contain the
// above machine independent information. // above machine independent information.
// //
@ -165,7 +167,7 @@ TShHandleBase* ConstructLinker(EShExecutable, int);
TShHandleBase* ConstructBindings(); TShHandleBase* ConstructBindings();
void DeleteLinker(TShHandleBase*); void DeleteLinker(TShHandleBase*);
void DeleteBindingList(TShHandleBase* bindingList); void DeleteBindingList(TShHandleBase* bindingList);
TUniformMap* ConstructUniformMap(); TUniformMap* ConstructUniformMap();
void DeleteCompiler(TCompiler*); void DeleteCompiler(TCompiler*);

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

705
Externals/glslang/glslang/Include/intermediate.h vendored Normal file → Executable file

File diff suppressed because it is too large Load Diff

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,4 +1,4 @@
// The file revision.h should be updated to the latest version, somehow, on // The file revision.h should be updated to the latest version, somehow, on
// check-in, if glslang has changed. // check-in, if glslang has changed.
// //
// revision.template is the source for revision.h when using SubWCRev as the // revision.template is the source for revision.h when using SubWCRev as the

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 {
@ -57,7 +59,7 @@ bool isNan(double x)
u.d = x; u.d = x;
int bitPatternL = u.i[0]; int bitPatternL = u.i[0];
int bitPatternH = u.i[1]; int bitPatternH = u.i[1];
return (bitPatternH & 0x7ff80000) == 0x7ff80000 && return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0); ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
} }
@ -68,7 +70,7 @@ bool isInf(double x)
u.d = x; u.d = x;
int bitPatternL = u.i[0]; int bitPatternL = u.i[0];
int bitPatternH = u.i[1]; int bitPatternH = u.i[1];
return (bitPatternH & 0x7ff00000) == 0x7ff00000 && return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
(bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0; (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
} }
@ -131,7 +133,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]); TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]);
rightUnionArray = smearedArray; rightUnionArray = smearedArray;
} else if (constComps > 1 && newComps == 1) { } else if (constComps > 1 && newComps == 1) {
// for a case like vec4 f = 1.2 + vec4(2,3,4,5); // for a case like vec4 f = 1.2 + vec4(2,3,4,5);
newComps = constComps; newComps = constComps;
rightUnionArray = rightNode->getConstArray(); rightUnionArray = rightNode->getConstArray();
TConstUnionArray smearedArray(newComps, getConstArray()[0]); TConstUnionArray smearedArray(newComps, getConstArray()[0]);
@ -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,8 +277,31 @@ 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 {
newConstArray[i] = leftUnionArray[i] % rightUnionArray[i]; 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];
}
}
} }
break; break;
@ -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;
} }
@ -620,9 +699,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
// //
// Do constant folding for an aggregate node that has all its children // Do constant folding for an aggregate node that has all its children
// as constants and an operator that requires constant folding. // as constants and an operator that requires constant folding.
// //
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;
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); case EbtUint8:
} else { newConstArray[comp].setU8Const(std::min(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()));
if (isInt64) break;
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); case EbtInt16:
else newConstArray[comp].setI16Const(std::min(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()));
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); 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()));
break;
case EbtUint:
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;
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); case EbtUint8:
} else { newConstArray[comp].setU8Const(std::max(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()));
if (isInt64) break;
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); case EbtInt16:
else newConstArray[comp].setI16Const(std::max(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()));
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); 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()));
break;
case EbtUint:
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;
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()), 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()),
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()), newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
childConstUnions[2][arg2comp].getU64Const()));
else
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:
@ -793,7 +928,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
break; break;
case EOpSmoothStep: case EOpSmoothStep:
{ {
double t = (childConstUnions[2][arg2comp].getDConst() - childConstUnions[0][arg0comp].getDConst()) / double t = (childConstUnions[2][arg2comp].getDConst() - childConstUnions[0][arg0comp].getDConst()) /
(childConstUnions[1][arg1comp].getDConst() - childConstUnions[0][arg0comp].getDConst()); (childConstUnions[1][arg1comp].getDConst() - childConstUnions[0][arg0comp].getDConst());
if (t < 0.0) if (t < 0.0)
t = 0.0; t = 0.0;
@ -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)
@ -959,23 +1094,23 @@ 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,31 +18,35 @@
// 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) {
checkMem(strlen(s)); if (s == nullptr)
sink.append(s); sink.append("(null)");
else {
checkMem(strlen(s));
sink.append(s);
}
} }
//#ifdef _WIN32 //#ifdef _WIN32
@ -54,11 +58,11 @@ void TInfoSinkBase::append(const char* s)
fprintf(stdout, "%s", s); fprintf(stdout, "%s", s);
} }
void TInfoSinkBase::append(int count, char c) void TInfoSinkBase::append(int count, char c)
{ {
if (outputStream & EString) { if (outputStream & EString) {
checkMem(count); checkMem(count);
sink.append(count, c); sink.append(count, c);
} }
//#ifdef _WIN32 //#ifdef _WIN32
@ -74,11 +78,11 @@ void TInfoSinkBase::append(int count, char c)
fprintf(stdout, "%c", c); fprintf(stdout, "%c", c);
} }
void TInfoSinkBase::append(const TPersistString& t) void TInfoSinkBase::append(const TPersistString& t)
{ {
if (outputStream & EString) { if (outputStream & EString) {
checkMem(t.size()); checkMem(t.size());
sink.append(t); sink.append(t);
} }
//#ifdef _WIN32 //#ifdef _WIN32
@ -91,10 +95,10 @@ void TInfoSinkBase::append(const TPersistString& t)
} }
void TInfoSinkBase::append(const TString& t) void TInfoSinkBase::append(const TString& t)
{ {
if (outputStream & EString) { if (outputStream & EString) {
checkMem(t.size()); checkMem(t.size());
sink.append(t.c_str()); sink.append(t.c_str());
} }
//#ifdef _WIN32 //#ifdef _WIN32

5394
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

2401
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);
} }
TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
bool tokensBeforeEOF; 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
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;
@ -375,7 +489,7 @@ protected:
// * note, that appropriately gives an error if redeclaring a block that // * note, that appropriately gives an error if redeclaring a block that
// was already used and hence already copied-up // was already used and hence already copied-up
// //
// - on seeing a layout declaration that sizes the array, fix everything in the // - on seeing a layout declaration that sizes the array, fix everything in the
// resize-list, giving errors for mismatch // resize-list, giving errors for mismatch
// //
// - on seeing an array size declaration, give errors on mismatch between it and previous // - on seeing an array size declaration, give errors on mismatch between it and previous

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,35 +65,15 @@ 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.
// //
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)
{ {
// //
@ -149,12 +116,12 @@ TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
TPoolAllocator::~TPoolAllocator() TPoolAllocator::~TPoolAllocator()
{ {
while (inUseList) { while (inUseList) {
tHeader* next = inUseList->nextPage; tHeader* next = inUseList->nextPage;
inUseList->~tHeader(); inUseList->~tHeader();
delete [] reinterpret_cast<char*>(inUseList); delete [] reinterpret_cast<char*>(inUseList);
inUseList = next; inUseList = next;
} }
// //
// Always delete the free list memory - it can't be being // Always delete the free list memory - it can't be being
@ -206,13 +173,12 @@ 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 };
stack.push_back(state); stack.push_back(state);
// //
// Indicate there is no current page to allocate from. // Indicate there is no current page to allocate from.
// //
@ -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;
} }
@ -269,7 +238,7 @@ void* TPoolAllocator::allocate(size_t numBytes)
// size including guard blocks. In release build, // size including guard blocks. In release build,
// guardBlockSize=0 and this all gets optimized away. // guardBlockSize=0 and this all gets optimized away.
size_t allocationSize = TAllocation::allocationSize(numBytes); size_t allocationSize = TAllocation::allocationSize(numBytes);
// //
// Just keep some interesting statistics. // Just keep some interesting statistics.
// //
@ -327,14 +296,13 @@ void* TPoolAllocator::allocate(size_t numBytes)
// Use placement-new to initialize header // Use placement-new to initialize header
new(memory) tHeader(inUseList, 1); new(memory) tHeader(inUseList, 1);
inUseList = memory; inUseList = memory;
unsigned char* ret = reinterpret_cast<unsigned char*>(inUseList) + headerSkip; unsigned char* ret = reinterpret_cast<unsigned char*>(inUseList) + headerSkip;
currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask; currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
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"
@ -55,7 +57,7 @@
// Required to avoid missing prototype warnings for some compilers // Required to avoid missing prototype warnings for some compilers
int yylex(YYSTYPE*, glslang::TParseContext&); int yylex(YYSTYPE*, glslang::TParseContext&);
namespace glslang { namespace glslang {
// read past any white space // read past any white space
@ -142,13 +144,13 @@ void TInputScanner::consumeWhitespaceComment(bool& foundNonSpaceTab)
{ {
do { do {
consumeWhiteSpace(foundNonSpaceTab); consumeWhiteSpace(foundNonSpaceTab);
// if not starting a comment now, then done // if not starting a comment now, then done
int c = peek(); int c = peek();
if (c != '/' || c == EndOfInput) if (c != '/' || c == EndOfInput)
return; return;
// skip potential comment // skip potential comment
foundNonSpaceTab = true; foundNonSpaceTab = true;
if (! consumeComment()) if (! consumeComment())
return; return;
@ -175,7 +177,7 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT
bool versionNotFirst = false; // means not first WRT comments and white space, nothing more bool versionNotFirst = false; // means not first WRT comments and white space, nothing more
notFirstToken = false; // means not first WRT to real tokens notFirstToken = false; // means not first WRT to real tokens
version = 0; // means not found version = 0; // means not found
profile = ENoProfile; profile = ENoProfile;
bool foundNonSpaceTab = false; bool foundNonSpaceTab = false;
@ -199,10 +201,10 @@ bool TInputScanner::scanVersion(int& version, EProfile& profile, bool& notFirstT
} }
lookingInMiddle = true; lookingInMiddle = true;
// Nominal start, skipping the desktop allowed comments and white space, but tracking if // Nominal start, skipping the desktop allowed comments and white space, but tracking if
// something else was found for ES: // something else was found for ES:
consumeWhitespaceComment(foundNonSpaceTab); consumeWhitespaceComment(foundNonSpaceTab);
if (foundNonSpaceTab) if (foundNonSpaceTab)
versionNotFirst = true; versionNotFirst = true;
// "#" // "#"
@ -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;
@ -561,7 +693,7 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["superp"] = SUPERP; (*KeywordMap)["superp"] = SUPERP;
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>; ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
ReservedSet->insert("common"); ReservedSet->insert("common");
ReservedSet->insert("partition"); ReservedSet->insert("partition");
ReservedSet->insert("active"); ReservedSet->insert("active");
@ -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;
@ -675,13 +810,20 @@ 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 PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; case PpAtomColonColon:
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; parseContext.error(loc, "not supported", "::", "");
case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT; break;
case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; 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 PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
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) ||
@ -774,7 +922,7 @@ int TScanContext::tokenizeIdentifier()
return keyword; return keyword;
case BUFFER: case BUFFER:
if ((parseContext.profile == EEsProfile && parseContext.version < 310) || if ((parseContext.profile == EEsProfile && parseContext.version < 310) ||
(parseContext.profile != EEsProfile && parseContext.version < 430)) (parseContext.profile != EEsProfile && parseContext.version < 430))
return identifierOrType(); return identifierOrType();
return keyword; return keyword;
@ -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);
@ -847,7 +999,7 @@ int TScanContext::tokenizeIdentifier()
case MAT3X4: case MAT3X4:
case MAT4X2: case MAT4X2:
case MAT4X3: case MAT4X3:
case MAT4X4: case MAT4X4:
return matNxM(); return matNxM();
case DMAT2: case DMAT2:
@ -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();
@ -973,7 +1260,7 @@ int TScanContext::tokenizeIdentifier()
case USAMPLER2DARRAY: case USAMPLER2DARRAY:
afterType = true; afterType = true;
return nonreservedKeyword(300, 130); return nonreservedKeyword(300, 130);
case ISAMPLER2DRECT: case ISAMPLER2DRECT:
case USAMPLER2DRECT: case USAMPLER2DRECT:
afterType = true; afterType = true;
@ -981,17 +1268,19 @@ 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);
case SAMPLER2DMS: case SAMPLER2DMS:
case ISAMPLER2DMS: case ISAMPLER2DMS:
case USAMPLER2DMS: case USAMPLER2DMS:
@ -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) {
reservedWord(); if (!parseContext.extensionTurnedOn(E_GL_EXT_shadow_samplers))
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,20 +1397,87 @@ 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:
if ((parseContext.profile == EEsProfile && parseContext.version < 300) || if ((parseContext.profile == EEsProfile && parseContext.version < 300) ||
(parseContext.profile != EEsProfile && parseContext.version < 130)) (parseContext.profile != EEsProfile && parseContext.version < 130))
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) {
@ -1161,7 +1523,7 @@ int TScanContext::tokenizeIdentifier()
bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130; bool reserved = parseContext.profile == EEsProfile || parseContext.version >= 130;
return identifierOrReserved(reserved); return identifierOrReserved(reserved);
} }
default: default:
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc); parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
return 0; return 0;
@ -1292,8 +1654,9 @@ 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;
@ -1317,8 +1680,8 @@ int TScanContext::secondGenerationImage()
return keyword; return keyword;
} }
if (parseContext.symbolTable.atBuiltInLevel() || if (parseContext.symbolTable.atBuiltInLevel() ||
(parseContext.profile != EEsProfile && (parseContext.profile != EEsProfile &&
(parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store))))
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) {
@ -252,7 +253,7 @@ protected:
size_t currentChar; size_t currentChar;
// This is for reporting what string/line an error occurred on, and can be overridden by #line. // This is for reporting what string/line an error occurred on, and can be overridden by #line.
// It remembers the last state of each source string as it is left for the next one, so unget() // It remembers the last state of each source string as it is left for the next one, so unget()
// can restore that state. // can restore that state.
TSourceLoc* loc; // an array TSourceLoc* loc; // an array

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:
mangledName += "struct-"; case EbtBlock:
if (basicType == EbtStruct)
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) {
@ -250,7 +280,7 @@ TSymbol::TSymbol(const TSymbol& copyOf)
} }
TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf) TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
{ {
type.deepCopy(copyOf.type); type.deepCopy(copyOf.type);
userType = copyOf.userType; userType = copyOf.userType;
numExtensions = 0; numExtensions = 0;
@ -276,7 +306,7 @@ TVariable* TVariable::clone() const
} }
TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf) TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
{ {
for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
TParameter param; TParameter param;
parameters.push_back(param); parameters.push_back(param);
@ -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; }
@ -120,7 +126,7 @@ protected:
const TString *name; const TString *name;
unsigned int uniqueId; // For cross-scope comparing during code generation unsigned int uniqueId; // For cross-scope comparing during code generation
// For tracking what extensions must be present // For tracking what extensions must be present
// (don't use if correct version/profile is present). // (don't use if correct version/profile is present).
int numExtensions; int numExtensions;
const char** extensions; // an array of pointers to existing constant char strings const char** extensions; // an array of pointers to existing constant char strings
@ -145,9 +151,10 @@ protected:
class TVariable : public TSymbol { class TVariable : public TSymbol {
public: 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,14 +197,17 @@ protected:
struct TParameter { struct TParameter {
TString *name; TString *name;
TType* type; TType* type;
void copyParam(const TParameter& param) TIntermTyped* defaultValue;
void copyParam(const TParameter& param)
{ {
if (param.name) if (param.name)
name = NewPoolTString(param.name->c_str()); name = NewPoolTString(param.name->c_str());
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;
}; };
// //
@ -268,7 +331,7 @@ public:
virtual const TAnonMember* getAsAnonMember() const { return this; } virtual const TAnonMember* getAsAnonMember() const { return this; }
virtual const TVariable& getAnonContainer() const { return anonContainer; } virtual const TVariable& getAnonContainer() const { return anonContainer; }
virtual unsigned int getMemberNumber() const { return memberNumber; } virtual unsigned int getMemberNumber() const { return memberNumber; }
virtual const TType& getType() const virtual const TType& getType() const
{ {
const TTypeList& types = *anonContainer.getType().getStruct(); const TTypeList& types = *anonContainer.getType().getStruct();
@ -281,7 +344,7 @@ public:
const TTypeList& types = *anonContainer.getType().getStruct(); const TTypeList& types = *anonContainer.getType().getStruct();
return *types[memberNumber].type; return *types[memberNumber].type;
} }
virtual int getAnonId() const { return anonId; } virtual int getAnonId() const { return anonId; }
virtual void dump(TInfoSink &infoSink) const; virtual void dump(TInfoSink &infoSink) const;
@ -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,24 +392,45 @@ 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
{ {
tLevel::const_iterator it = level.find(name); tLevel::const_iterator it = level.find(name);
if (it == level.end()) if (it == level.end())
return 0; return 0;
else else
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 {
@ -474,7 +552,7 @@ public:
while (table.size() > adoptedLevels) while (table.size() > adoptedLevels)
pop(0); pop(0);
} }
void adoptLevels(TSymbolTable& symTable) void adoptLevels(TSymbolTable& symTable)
{ {
for (unsigned int level = 0; level < symTable.table.size(); ++level) { for (unsigned int level = 0; level < symTable.table.size(); ++level) {
@ -506,12 +584,26 @@ public:
void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
void setSeparateNameSpaces() { separateNameSpaces = true; } void setSeparateNameSpaces() { separateNameSpaces = true; }
void push() void push()
{ {
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);
@ -532,7 +624,7 @@ public:
// make sure there isn't a function of this variable name // make sure there isn't a function of this variable name
if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName())) if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName()))
return false; return false;
// check for not overloading or redefining a built-in function // check for not overloading or redefining a built-in function
if (noBuiltInRedeclarations) { if (noBuiltInRedeclarations) {
if (atGlobalLevel() && currentLevel() > 0) { if (atGlobalLevel() && currentLevel() > 0) {
@ -546,9 +638,17 @@ 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
// found by doing a symbol table search by name, hence allowed an // found by doing a symbol table search by name, hence allowed an
// arbitrary name in the symbol with no worry of collision. // arbitrary name in the symbol with no worry of collision.
// //
@ -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;
@ -650,7 +781,7 @@ public:
for (unsigned int level = 0; level < table.size(); ++level) for (unsigned int level = 0; level < table.size(); ++level)
table[level]->relateToOperator(name, op); table[level]->relateToOperator(name, op);
} }
void setFunctionExtensions(const char* name, int num, const char* const extensions[]) void setFunctionExtensions(const char* name, int num, const char* const extensions[])
{ {
for (unsigned int level = 0; level < table.size(); ++level) for (unsigned int level = 0; level < table.size(); ++level)

395
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,24 +21,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.
// //
// //
// Help manage multiple profiles, versions, extensions etc. // Help manage multiple profiles, versions, extensions etc.
// //
// These don't return error codes, as the presumption is parsing will // These don't return error codes, as the presumption is parsing will
// always continue as if the tested feature were enabled, and thus there // always continue as if the tested feature were enabled, and thus there
// is no error recovery needed. // is no error recovery needed.
// //
@ -47,25 +48,25 @@
// //
// To add a new hypothetical "Feature F" to the front end, where an extension // To add a new hypothetical "Feature F" to the front end, where an extension
// "XXX_extension_X" can be used to enable the feature, do the following. // "XXX_extension_X" can be used to enable the feature, do the following.
// //
// OVERVIEW: Specific features are what are error-checked for, not // OVERVIEW: Specific features are what are error-checked for, not
// extensions: A specific Feature F might be enabled by an extension, or a // extensions: A specific Feature F might be enabled by an extension, or a
// particular version in a particular profile, or a stage, or combinations, etc. // particular version in a particular profile, or a stage, or combinations, etc.
// //
// The basic mechanism is to use the following to "declare" all the things that // The basic mechanism is to use the following to "declare" all the things that
// enable/disable Feature F, in a code path that implements Feature F: // enable/disable Feature F, in a code path that implements Feature F:
// //
// requireProfile() // requireProfile()
// profileRequires() // profileRequires()
// requireStage() // requireStage()
// checkDeprecated() // checkDeprecated()
// requireNotRemoved() // requireNotRemoved()
// requireExtensions() // requireExtensions()
// //
// Typically, only the first two calls are needed. They go into a code path that // Typically, only the first two calls are needed. They go into a code path that
// implements Feature F, and will log the proper error/warning messages. Parsing // implements Feature F, and will log the proper error/warning messages. Parsing
// will then always continue as if the tested feature was enabled. // will then always continue as if the tested feature was enabled.
// //
// There is typically no if-testing or conditional parsing, just insertion of the calls above. // There is typically no if-testing or conditional parsing, just insertion of the calls above.
// However, if symbols specific to the extension are added (step 5), they will // However, if symbols specific to the extension are added (step 5), they will
// only be added under tests that the minimum version and profile are present. // only be added under tests that the minimum version and profile are present.
@ -73,10 +74,10 @@
// 1) Add a symbol name for the extension string at the bottom of Versions.h: // 1) Add a symbol name for the extension string at the bottom of Versions.h:
// //
// const char* const XXX_extension_X = "XXX_extension_X"; // const char* const XXX_extension_X = "XXX_extension_X";
// //
// 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(), // 2) Add extension initialization to TParseVersions::initializeExtensionBehavior(),
// the first function below: // the first function below:
// //
// extensionBehavior[XXX_extension_X] = EBhDisable; // extensionBehavior[XXX_extension_X] = EBhDisable;
// //
// 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble(): // 3) Add any preprocessor directives etc. in the next function, TParseVersions::getPreamble():
@ -84,50 +85,50 @@
// "#define XXX_extension_X 1\n" // "#define XXX_extension_X 1\n"
// //
// The new-line is important, as that ends preprocess tokens. // The new-line is important, as that ends preprocess tokens.
// //
// 4) Insert a profile check in the feature's path (unless all profiles support the feature, // 4) Insert a profile check in the feature's path (unless all profiles support the feature,
// for some version level). That is, call requireProfile() to constrain the profiles, e.g.: // for some version level). That is, call requireProfile() to constrain the profiles, e.g.:
// //
// // ... in a path specific to Feature F... // // ... in a path specific to Feature F...
// requireProfile(loc, // requireProfile(loc,
// ECoreProfile | ECompatibilityProfile, // ECoreProfile | ECompatibilityProfile,
// "Feature F"); // "Feature F");
// //
// 5) For each profile that supports the feature, insert version/extension checks: // 5) For each profile that supports the feature, insert version/extension checks:
// //
// The mostly likely scenario is that Feature F can only be used with a // The mostly likely scenario is that Feature F can only be used with a
// particular profile if XXX_extension_X is present or the version is // particular profile if XXX_extension_X is present or the version is
// high enough that the core specification already incorporated it. // high enough that the core specification already incorporated it.
// //
// // following the requireProfile() call... // // following the requireProfile() call...
// profileRequires(loc, // profileRequires(loc,
// ECoreProfile | ECompatibilityProfile, // ECoreProfile | ECompatibilityProfile,
// 420, // 0 if no version incorporated the feature into the core spec. // 420, // 0 if no version incorporated the feature into the core spec.
// XXX_extension_X, // can be a list of extensions that all add the feature // XXX_extension_X, // can be a list of extensions that all add the feature
// "Feature F Description"); // "Feature F Description");
// //
// This allows the feature if either A) one of the extensions is enabled or // This allows the feature if either A) one of the extensions is enabled or
// B) the version is high enough. If no version yet incorporates the feature // B) the version is high enough. If no version yet incorporates the feature
// into core, pass in 0. // into core, pass in 0.
// //
// This can be called multiple times, if different profiles support the // This can be called multiple times, if different profiles support the
// feature starting at different version numbers or with different // feature starting at different version numbers or with different
// extensions. // extensions.
// //
// This must be called for each profile allowed by the initial call to requireProfile(). // This must be called for each profile allowed by the initial call to requireProfile().
// //
// Profiles are all masks, which can be "or"-ed together. // Profiles are all masks, which can be "or"-ed together.
// //
// ENoProfile // ENoProfile
// ECoreProfile // ECoreProfile
// ECompatibilityProfile // ECompatibilityProfile
// EEsProfile // EEsProfile
// //
// The ENoProfile profile is only for desktop, before profiles showed up in version 150; // The ENoProfile profile is only for desktop, before profiles showed up in version 150;
// All other #version with no profile default to either es or core, and so have profiles. // All other #version with no profile default to either es or core, and so have profiles.
// //
// You can select all but a particular profile using ~. The following basically means "desktop": // You can select all but a particular profile using ~. The following basically means "desktop":
// //
// ~EEsProfile // ~EEsProfile
// //
// 6) If built-in symbols are added by the extension, add them in Initialize.cpp: Their use // 6) If built-in symbols are added by the extension, add them in Initialize.cpp: Their use
@ -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,
@ -221,14 +282,16 @@ void TParseVersions::initializeExtensionBehavior()
void TParseVersions::getPreamble(std::string& preamble) void TParseVersions::getPreamble(std::string& preamble)
{ {
if (profile == EEsProfile) { if (profile == EEsProfile) {
preamble = preamble =
"#define GL_ES 1\n" "#define GL_ES 1\n"
"#define GL_FRAGMENT_PRECISION_HIGH 1\n" "#define GL_FRAGMENT_PRECISION_HIGH 1\n"
"#define GL_OES_texture_3D 1\n" "#define GL_OES_texture_3D 1\n"
"#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,8 +322,15 @@ 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"
"#define GL_ARB_texture_rectangle 1\n" "#define GL_ARB_texture_rectangle 1\n"
"#define GL_ARB_shading_language_420pack 1\n" "#define GL_ARB_shading_language_420pack 1\n"
@ -284,13 +354,82 @@ 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"
; ;
} }
// #line and #include // #line and #include
preamble += preamble +=
"#define GL_GOOGLE_cpp_style_line_directive 1\n" "#define GL_GOOGLE_cpp_style_line_directive 1\n"
"#define GL_GOOGLE_include_directive 1\n" "#define GL_GOOGLE_include_directive 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";
} }
@ -317,7 +456,7 @@ void TParseVersions::getPreamble(std::string& preamble)
// //
// When to use requireProfile(): // When to use requireProfile():
// //
// Use if only some profiles support a feature. However, if within a profile the feature // Use if only some profiles support a feature. However, if within a profile the feature
// is version or extension specific, follow this call with calls to profileRequires(). // is version or extension specific, follow this call with calls to profileRequires().
// //
// Operation: If the current profile is not one of the profileMask, // Operation: If the current profile is not one of the profileMask,
@ -332,7 +471,7 @@ void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, cons
// //
// Map from stage enum to externally readable text name. // Map from stage enum to externally readable text name.
// //
const char* StageName(EShLanguage stage) const char* StageName(EShLanguage stage)
{ {
switch(stage) { switch(stage) {
case EShLangVertex: return "vertex"; case EShLangVertex: return "vertex";
@ -357,7 +496,7 @@ const char* StageName(EShLanguage stage)
// Operation: Will issue warnings/errors based on the current profile, version, and extension // Operation: Will issue warnings/errors based on the current profile, version, and extension
// behaviors. It only checks extensions when the current profile is one of the profileMask. // behaviors. It only checks extensions when the current profile is one of the profileMask.
// //
// A minVersion of 0 means no version of the profileMask support this in core, // A minVersion of 0 means no version of the profileMask support this in core,
// the extension must be present. // the extension must be present.
// //
@ -395,7 +534,7 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int
// //
// When to use requireStage() // When to use requireStage()
// //
// If only some stages support a feature. // If only some stages support a feature.
// //
// Operation: If the current stage is not present, give an error message. // Operation: If the current stage is not present, give an error message.
// //
@ -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)
@ -637,7 +803,7 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
// Call for any operation needing full GLSL integer data-type support. // Call for any operation needing full GLSL integer data-type support.
void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op) void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
{ {
profileRequires(loc, ENoProfile, 130, nullptr, op); profileRequires(loc, ENoProfile, 130, nullptr, op);
profileRequires(loc, EEsProfile, 300, nullptr, op); profileRequires(loc, EEsProfile, 300, nullptr, op);
} }
@ -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

768
Externals/glslang/glslang/MachineIndependent/intermOut.cpp vendored Normal file → Executable file

File diff suppressed because it is too large Load Diff

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.
// //
// //
@ -83,7 +83,7 @@ protected:
// check binary operations for those modifying the loop index // check binary operations for those modifying the loop index
bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
{ {
if (node->modifiesState() && node->getLeft()->getAsSymbolNode() && if (node->modifiesState() && node->getLeft()->getAsSymbolNode() &&
node->getLeft()->getAsSymbolNode()->getId() == loopId) { node->getLeft()->getAsSymbolNode()->getId() == loopId) {
bad = true; bad = true;
badLoc = node->getLoc(); badLoc = node->getLoc();
@ -95,7 +95,7 @@ bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
// check unary operations for those modifying the loop index // check unary operations for those modifying the loop index
bool TInductiveTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) bool TInductiveTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
{ {
if (node->modifiesState() && node->getOperand()->getAsSymbolNode() && if (node->modifiesState() && node->getOperand()->getAsSymbolNode() &&
node->getOperand()->getAsSymbolNode()->getId() == loopId) { node->getOperand()->getAsSymbolNode()->getId() == loopId) {
bad = true; bad = true;
badLoc = node->getLoc(); badLoc = node->getLoc();
@ -145,7 +145,7 @@ void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbo
// //
// The "constant-index-expression" tranverser. // The "constant-index-expression" tranverser.
// //
// Just look at things that can form an index. // Just look at things that can form an index.
// //
class TIndexTraverser : public TIntermTraverser { class TIndexTraverser : public TIntermTraverser {

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.
// //
// //
@ -48,7 +49,7 @@
#include "../Include/InfoSink.h" #include "../Include/InfoSink.h"
namespace glslang { namespace glslang {
// //
// Link-time error emitter. // Link-time error emitter.
// //
@ -60,8 +61,15 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message)
++numErrors; ++numErrors;
} }
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block // Link-time warning.
// name must have the exact same set of members qualified with offset and their integral-constant 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
// 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; numEntryPoints += unit.getNumEntryPoints();
numErrors += unit.numErrors; 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)
@ -103,12 +116,12 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
inputPrimitive = unit.inputPrimitive; inputPrimitive = unit.inputPrimitive;
else if (inputPrimitive != unit.inputPrimitive) else if (inputPrimitive != unit.inputPrimitive)
error(infoSink, "Contradictory input layout primitives"); error(infoSink, "Contradictory input layout primitives");
if (outputPrimitive == ElgNone) if (outputPrimitive == ElgNone)
outputPrimitive = unit.outputPrimitive; outputPrimitive = unit.outputPrimitive;
else if (outputPrimitive != unit.outputPrimitive) else if (outputPrimitive != unit.outputPrimitive)
error(infoSink, "Contradictory output layout primitives"); error(infoSink, "Contradictory output layout primitives");
if (vertices == TQualifier::layoutNotSet) if (vertices == TQualifier::layoutNotSet)
vertices = unit.vertices; vertices = unit.vertices;
else if (vertices != unit.vertices) { else if (vertices != unit.vertices) {
@ -169,7 +182,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
} }
// Getting this far means we have two existing trees to merge... // Getting this far means we have two existing trees to merge...
version = std::max(version, unit.version); version = std::max(version, unit.version);
requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end()); requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end());
@ -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,8 +297,13 @@ 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()) {
error(infoSink, "Types must match:"); // but, we make an exception if one is an implicit array and the other is sized
writeTypeComparison = true; if (! (symbol.getType().isArray() && unitSymbol.getType().isArray() &&
symbol.getType().sameElementType(unitSymbol.getType()) &&
(symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray()))) {
error(infoSink, "Types must match:");
writeTypeComparison = true;
}
} }
// Qualifiers have to (almost) match // Qualifiers have to (almost) match
@ -332,9 +353,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
writeTypeComparison = true; writeTypeComparison = true;
} }
// Layouts... // Layouts...
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec // TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
// requires separate user-supplied offset from actual computed offset, but // requires separate user-supplied offset from actual computed offset, but
// current implementation only has one offset. // current implementation only has one offset.
if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix || if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix ||
symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking || symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking ||
@ -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);
@ -400,7 +429,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
if (xfbBuffers[b].containsDouble) if (xfbBuffers[b].containsDouble)
RoundToPow2(xfbBuffers[b].implicitStride, 8); RoundToPow2(xfbBuffers[b].implicitStride, 8);
// "It is a compile-time or link-time error to have // "It is a compile-time or link-time error to have
// any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or // any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
// in different compilation units. While xfb_stride can be declared multiple times for the same buffer, it is a // in different compilation units. While xfb_stride can be declared multiple times for the same buffer, it is a
// compile-time or link-time error to have different values specified for the stride for the same buffer." // compile-time or link-time error to have different values specified for the stride for the same buffer."
@ -412,8 +441,8 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd) if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd)
xfbBuffers[b].stride = xfbBuffers[b].implicitStride; xfbBuffers[b].stride = xfbBuffers[b].implicitStride;
// "If the buffer is capturing any // "If the buffer is capturing any
// outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a // outputs with double-precision components, the stride must be a multiple of 8, otherwise it must be a
// multiple of 4, or a compile-time or link-time error results." // multiple of 4, or a compile-time or link-time error results."
if (xfbBuffers[b].containsDouble && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) { if (xfbBuffers[b].containsDouble && ! IsMultipleOfPow2(xfbBuffers[b].stride, 8)) {
error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double:"); error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double:");
@ -425,7 +454,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink)
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n"; infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
} }
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the // "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents." // implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) { if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
error(infoSink, "xfb_stride is too large:"); error(infoSink, "xfb_stride is too large:");
@ -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 (inputPrimitive == ElgNone) if (source == EShSourceGlsl) {
error(infoSink, "At least one shader must specify an input layout primitive"); if (inputPrimitive == ElgNone)
if (vertexSpacing == EvsNone) error(infoSink, "At least one shader must specify an input layout primitive");
vertexSpacing = EvsEqual; if (vertexSpacing == EvsNone)
if (vertexOrder == EvoNone) vertexSpacing = EvsEqual;
vertexOrder = EvoCcw; if (vertexOrder == EvoNone)
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;
@ -515,7 +561,7 @@ void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink)
break; break;
// Otherwise, we found a new subgraph, process it: // Otherwise, we found a new subgraph, process it:
// See what all can be reached by this new root, and if any of // See what all can be reached by this new root, and if any of
// that is recursive. This is done by depth-first traversals, seeing // that is recursive. This is done by depth-first traversals, seeing
// if a new call is found that was already in the currentPath (a back edge), // if a new call is found that was already in the currentPath (a back edge),
// thereby detecting recursion. // thereby detecting recursion.
@ -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
// //
@ -605,7 +730,7 @@ TIntermSequence& TIntermediate::findLinkerObjects() const
} }
// See if a variable was both a user-declared output and used. // See if a variable was both a user-declared output and used.
// Note: the spec discusses writing to one, but this looks at read or write, which // Note: the spec discusses writing to one, but this looks at read or write, which
// is more useful, and perhaps the spec should be changed to reflect that. // is more useful, and perhaps the spec should be changed to reflect that.
bool TIntermediate::userOutputUsed() const bool TIntermediate::userOutputUsed() const
{ {
@ -616,7 +741,7 @@ bool TIntermediate::userOutputUsed() const
const TIntermSymbol& symbolNode = *linkerObjects[i]->getAsSymbolNode(); const TIntermSymbol& symbolNode = *linkerObjects[i]->getAsSymbolNode();
if (symbolNode.getQualifier().storage == EvqVaryingOut && if (symbolNode.getQualifier().storage == EvqVaryingOut &&
symbolNode.getName().compare(0, 3, "gl_") != 0 && symbolNode.getName().compare(0, 3, "gl_") != 0 &&
inIoAccessed(symbolNode.getName())) { inIoAccessed(symbolNode.getName())) {
found = true; found = true;
break; break;
} }
@ -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);
} }
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1); // Locations, and components within locations.
TRange componentRange(0, 3); //
if (qualifier.hasComponent()) { // Almost always, dealing with components means a single location is involved.
componentRange.start = qualifier.layoutComponent; // The exception is a dvec3. From the spec:
componentRange.last = componentRange.start + type.getVectorSize() - 1; //
} // "A dvec3 will consume all four components of the first location and components 0 and 1 of
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0); // 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.
// check for collisions, except for vertex inputs on desktop int collision = -1; // no collision
if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput())) { if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
for (size_t r = 0; r < usedIo[set].size(); ++r) { (qualifier.isPipeInput() || qualifier.isPipeOutput())) {
if (range.overlap(usedIo[set][r])) { // Dealing with dvec3 in/out split across two locations.
// there is a collision; pick one // Need two io-ranges.
return std::max(locationRange.start, usedIo[set][r].location.start); // The case where the dvec3 doesn't start at component 0 was previously caught as overflow.
} else if (locationRange.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
// aliased-type mismatch // First range:
typeCollision = true; TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
return std::max(locationRange.start, usedIo[set][r].location.start); 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 componentRange(0, 3);
if (qualifier.hasComponent() || type.getVectorSize() > 0) {
int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1);
if (qualifier.hasComponent())
componentRange.start = qualifier.layoutComponent;
componentRange.last = componentRange.start + consumedComponents - 1;
}
// combine location and component ranges
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);
// check for collisions, except for vertex inputs on desktop targeting OpenGL
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) {
if (range.overlap(usedIo[set][r])) {
// there is a collision; pick one
return std::max(range.location.start, usedIo[set][r].location.start);
} else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
// aliased-type mismatch
typeCollision = true;
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,41 +918,41 @@ 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
// recursively..." // recursively..."
if (type.isStruct()) { if (type.isStruct()) {
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;
} }
// ES: "If a shader input is any scalar or vector type, it will consume a single location." // ES: "If a shader input is any scalar or vector type, it will consume a single location."
// Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex // Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex
// shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while // shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while
// types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will // types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will
// consume only a single location, in all stages." // consume only a single location, in all stages."
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;
@ -773,17 +961,48 @@ int TIntermediate::computeTypeLocationSize(const TType& type) const
} }
// "If the declared input is an n x m single- or double-precision matrix, ... // "If the declared input is an n x m single- or double-precision matrix, ...
// The number of locations assigned for each matrix will be the same as // The number of locations assigned for each matrix will be the same as
// 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.
@ -819,16 +1038,16 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
// N.B. Caller must set containsDouble to false before calling. // N.B. Caller must set containsDouble to false before calling.
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const
{ {
// "...if applied to an aggregate containing a double, the offset must also be a multiple of 8, // "...if applied to an aggregate containing a double, the offset must also be a multiple of 8,
// and the space taken in the buffer will be a multiple of 8. // and the space taken in the buffer will be a multiple of 8.
// ...within the qualified entity, subsequent components are each // ...within the qualified entity, subsequent components are each
// assigned, in order, to the next available offset aligned to a multiple of // assigned, in order, to the next available offset aligned to a multiple of
// that component's size. Aggregate types are flattened down to the component // that component's size. Aggregate types are flattened down to the component
// level to get this sequence of components." // level to get this sequence of components."
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);
} }
@ -838,8 +1057,8 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
bool structContainsDouble = false; bool structContainsDouble = false;
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);
// "... if applied to // "... if applied to
// an aggregate containing a double, the offset must also be a multiple of 8, // an aggregate containing a double, the offset must also be a multiple of 8,
// and the space taken in the buffer will be a multiple of 8." // and the space taken in the buffer will be a multiple of 8."
bool memberContainsDouble = false; bool memberContainsDouble = false;
int memberSize = computeTypeXfbSize(memberType, memberContainsDouble); int memberSize = computeTypeXfbSize(memberType, memberContainsDouble);
@ -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;
} }
} }
@ -894,7 +1118,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
// Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout // Implement base-alignment and size rules from section 7.6.2.2 Standard Uniform Block Layout
// Operates recursively. // Operates recursively.
// //
// If std140 is true, it does the rounding up to vec4 size required by std140, // If std140 is true, it does the rounding up to vec4 size required by std140,
// otherwise it does not, yielding std430 rules. // otherwise it does not, yielding std430 rules.
// //
// The size is returned in the 'size' parameter // The size is returned in the 'size' parameter
@ -923,7 +1147,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
// //
// 1. If the member is a scalar consuming N basic machine units, the base alignment is N. // 1. If the member is a scalar consuming N basic machine units, the base alignment is N.
// //
// 2. If the member is a two- or four-component vector with components consuming N basic // 2. If the member is a two- or four-component vector with components consuming N basic
// machine units, the base alignment is 2N or 4N, respectively. // machine units, the base alignment is 2N or 4N, respectively.
// //
// 3. If the member is a three-component vector with components consuming N // 3. If the member is a three-component vector with components consuming N
@ -936,11 +1160,11 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
// the array is rounded up to the next multiple of the base alignment. // the array is rounded up to the next multiple of the base alignment.
// //
// 5. If the member is a column-major matrix with C columns and R rows, the // 5. If the member is a column-major matrix with C columns and R rows, the
// matrix is stored identically to an array of C column vectors with R // matrix is stored identically to an array of C column vectors with R
// 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,12 +1172,12 @@ 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
// N is the largest base alignment value of any of its members, and rounded // N is the largest base alignment value of any of its members, and rounded
// up to the base alignment of a vec4. The individual members of this substructure // up to the base alignment of a vec4. The individual members of this substructure
// are then assigned offsets by applying this set of rules recursively, // are then assigned offsets by applying this set of rules recursively,
// where the base offset of the first member of the sub-structure is equal to the // where the base offset of the first member of the sub-structure is equal to the
// aligned offset of the structure. The structure may have padding at the end; // aligned offset of the structure. The structure may have padding at the end;
@ -995,7 +1219,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140, int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140,
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor); (subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
maxAlignment = std::max(maxAlignment, memberAlignment); maxAlignment = std::max(maxAlignment, memberAlignment);
RoundToPow2(size, memberAlignment); RoundToPow2(size, memberAlignment);
size += memberSize; size += memberSize;
} }
@ -1015,10 +1239,12 @@ 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;
default: default:
size *= type.getVectorSize(); size *= type.getVectorSize();
return 4 * scalarAlign; return 4 * scalarAlign;
} }
@ -1028,7 +1254,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
if (type.isMatrix()) { if (type.isMatrix()) {
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows // rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
TType derefType(type, 0, rowMajor); TType derefType(type, 0, rowMajor);
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor); alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
if (std140) if (std140)
alignment = std::max(baseAlignmentVec4Std140, alignment); alignment = std::max(baseAlignmentVec4Std140, alignment);
@ -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

455
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,12 +100,13 @@ 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.
struct TRange { struct TRange {
TRange(int start, int last) : start(start), last(last) { } TRange(int start, int last) : start(start), last(last) { }
bool overlap(const TRange& rhs) const bool overlap(const TRange& rhs) const
{ {
return last >= rhs.start && start <= rhs.last; return last >= rhs.start && start <= rhs.last;
} }
@ -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,53 +411,77 @@ 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)
{ {
if (invocations != TQualifier::layoutNotSet) if (invocations != TQualifier::layoutNotSet)
return invocations == i; return invocations == i;
@ -259,7 +523,7 @@ public:
TVertexOrder getVertexOrder() const { return vertexOrder; } TVertexOrder getVertexOrder() const { return vertexOrder; }
void setPointMode() { pointMode = true; } void setPointMode() { pointMode = true; }
bool getPointMode() const { return pointMode; } bool getPointMode() const { return pointMode; }
bool setLocalSize(int dim, int size) bool setLocalSize(int dim, int size)
{ {
if (localSize[dim] > 1) if (localSize[dim] > 1)
@ -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.
// //
@ -45,7 +45,7 @@ class TConstTraverser : public TIntermTraverser {
public: public:
TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t) TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t)
: unionArray(cUnion), type(t), : unionArray(cUnion), type(t),
constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false), constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false),
matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; } matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; }
virtual void visitConstantUnion(TIntermConstantUnion* node); virtual void visitConstantUnion(TIntermConstantUnion* node);
@ -73,18 +73,12 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
if (! node->isConstructor() && node->getOp() != EOpComma) { if (! node->isConstructor() && node->getOp() != EOpComma) {
error = true; error = true;
return false;
}
if (node->getSequence().size() == 0) {
error = true;
return false; 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;
constructorType = node->getOp(); constructorType = node->getOp();
size = node->getType().computeNumComponents(); size = node->getType().computeNumComponents();
@ -93,19 +87,19 @@ bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
matrixCols = node->getType().getMatrixCols(); matrixCols = node->getType().getMatrixCols();
matrixRows = node->getType().getMatrixRows(); matrixRows = node->getType().getMatrixRows();
} }
} }
for (TIntermSequence::iterator p = node->getSequence().begin(); for (TIntermSequence::iterator p = node->getSequence().begin();
p != node->getSequence().end(); p++) { p != node->getSequence().end(); p++) {
if (node->getOp() == EOpComma) if (node->getOp() == EOpComma)
index = 0; index = 0;
(*p)->traverse(this); (*p)->traverse(this);
} }
if (flag) if (flag)
{ {
singleConstantParam = false; singleConstantParam = false;
constructorType = EOpNull; constructorType = EOpNull;
size = 0; size = 0;
isMatrix = false; isMatrix = false;
@ -126,7 +120,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
if (! singleConstantParam) { if (! singleConstantParam) {
int rightUnionSize = node->getType().computeNumComponents(); int rightUnionSize = node->getType().computeNumComponents();
const TConstUnionArray& rightUnionArray = node->getConstArray(); const TConstUnionArray& rightUnionArray = node->getConstArray();
for (int i = 0; i < rightUnionSize; i++) { for (int i = 0; i < rightUnionSize; i++) {
if (index >= instanceSize) if (index >= instanceSize)
@ -148,7 +142,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
leftUnionArray[i] = rightUnionArray[count]; leftUnionArray[i] = rightUnionArray[count];
(index)++; (index)++;
if (nodeComps > 1) if (nodeComps > 1)
count++; count++;
} }
@ -180,13 +174,13 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
return; return;
if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 ) if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
leftUnionArray[i] = rightUnionArray[count]; leftUnionArray[i] = rightUnionArray[count];
else else
leftUnionArray[i].setDConst(0.0); leftUnionArray[i].setDConst(0.0);
index++; index++;
if (nodeComps > 1) if (nodeComps > 1)
count++; count++;
} }
} }
} }
@ -199,7 +193,7 @@ bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArra
return false; return false;
TConstTraverser it(unionArray, singleConstantParam, constructorType, t); TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
root->traverse(&it); root->traverse(&it);
if (it.error) if (it.error)
return true; return 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&);
}; };

File diff suppressed because it is too large Load Diff

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.
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder. incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
@ -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" },
@ -121,56 +146,20 @@ const struct {
{ PpAtomFileMacro, "__FILE__" }, { PpAtomFileMacro, "__FILE__" },
{ 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.
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder. incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
@ -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

332
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.
@ -56,7 +56,7 @@ Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder. incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
@ -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,28 +93,92 @@ namespace glslang {
class TPpToken { class TPpToken {
public: public:
TPpToken() : token(0), space(false), ival(0), dval(0.0), atom(0) TPpToken() { clear(); }
void clear()
{ {
loc.init(); space = false;
i64val = 0;
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:
int ival; bool space;
double dval; // Numeric value of the token:
long long i64val; union {
int atom; int ival;
char name[MaxTokenLength + 1]; double dval;
long long i64val;
};
// Text string of the token:
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;
@ -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,34 +311,47 @@ 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
int elsetracker; // #if-#else and #endif constructs...Counter. int elsetracker; // #if-#else and #endif constructs...Counter.
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,60 +383,49 @@ 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);
int extraTokenCheck(int atom, TPpToken* ppToken, int token); int extraTokenCheck(int atom, TPpToken* ppToken, int token);
int eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken * ppToken); int eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
int evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken * ppToken); int evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken * ppToken);
int CPPif (TPpToken * ppToken); int CPPif (TPpToken * ppToken);
int CPPifdef(int defined, TPpToken * ppToken); int CPPifdef(int defined, TPpToken * ppToken);
int CPPinclude(TPpToken * ppToken); int CPPinclude(TPpToken * ppToken);
int CPPline(TPpToken * ppToken); int CPPline(TPpToken * ppToken);
int CPPerror(TPpToken * ppToken); int CPPerror(TPpToken * ppToken);
int CPPpragma(TPpToken * ppToken); int CPPpragma(TPpToken * ppToken);
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();
@ -387,7 +465,7 @@ protected:
return '\\'; return '\\';
} while (ch == '\\'); } while (ch == '\\');
} }
// handle any non-escaped newline // handle any non-escaped newline
if (ch == '\r' || ch == '\n') { if (ch == '\r' || ch == '\n') {
if (ch == '\r' && input->peek() == '\n') if (ch == '\r' && input->peek() == '\n')
@ -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();
@ -432,7 +510,7 @@ protected:
TInputScanner* input; TInputScanner* input;
}; };
// Holds a reference to included file data, as well as a // Holds a reference to included file data, as well as a
// prologue and an epilogue string. This can be scanned using the tInput // prologue and an epilogue string. This can be scanned using the tInput
// interface and acts as a single source string. // interface and acts as a single source string.
class TokenizableIncludeFile : public tInput { class TokenizableIncludeFile : public tInput {
@ -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

354
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.
@ -57,7 +57,7 @@ Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder. incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
@ -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: // save the numeric value
case PpAtomConstInt64: if (SaveValue(atom)) {
case PpAtomConstUint64: const char* n = reinterpret_cast<const char*>(&ppToken->i64val);
case PpAtomConstFloat: for (int i = 0; i < sizeof(ppToken->i64val); ++i)
case PpAtomConstDouble: putSubtoken(*n++);
str = ppToken->name;
while (*str) {
lAddByte(pTok, (unsigned char) *str);
str++;
}
lAddByte(pTok, 0);
break;
default:
break;
} }
} }
/* // 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.
@ -56,7 +56,7 @@ Except as expressly stated in this notice, no other rights or licenses
express or implied, are granted by NVIDIA herein, including but not express or implied, are granted by NVIDIA herein, including but not
limited to any patent rights that may be infringed by your derivative limited to any patent rights that may be infringed by your derivative
works or by other works in which the NVIDIA Software may be works or by other works in which the NVIDIA Software may be
incorporated. No hardware is licensed hereunder. incorporated. No hardware is licensed hereunder.
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
@ -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,

Some files were not shown because too many files have changed in this diff Show More