Merge remote-tracking branch 'origin/master' into dev
This commit is contained in:
commit
1858cf3b33
|
@ -1,5 +1,5 @@
|
|||
freebsd_instance:
|
||||
image_family: freebsd-13-0
|
||||
image_family: freebsd-13-1
|
||||
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache
|
||||
|
|
|
@ -31,7 +31,7 @@ jobs:
|
|||
run: |
|
||||
brew update
|
||||
brew install libao ldid ninja pulseaudio
|
||||
VULKAN_VER=1.3.211.0 && aria2c --parameterized-uri=true https://{sdk.lunarg.com/sdk/download/$VULKAN_VER/mac,distfiles.macports.org/MoltenVK}/vulkansdk-macos-$VULKAN_VER.dmg
|
||||
VULKAN_VER=1.3.224.1 && aria2c --parameterized-uri=true https://{sdk.lunarg.com/sdk/download/$VULKAN_VER/mac,distfiles.macports.org/MoltenVK}/vulkansdk-macos-$VULKAN_VER.dmg
|
||||
hdiutil attach ./vulkansdk-macos-*.dmg
|
||||
sudo /Volumes/vulkansdk-macos-*/InstallVulkan.app/Contents/MacOS/InstallVulkan --root $HOME/VulkanSDK --accept-licenses --default-answer --confirm-command install
|
||||
hdiutil detach /Volumes/vulkansdk-macos-*
|
||||
|
|
|
@ -10,3 +10,15 @@
|
|||
[submodule "core/deps/breakpad"]
|
||||
path = core/deps/breakpad
|
||||
url = https://github.com/flyinghead/mingw-breakpad
|
||||
[submodule "core/deps/Vulkan-Headers"]
|
||||
path = core/deps/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
[submodule "core/deps/VulkanMemoryAllocator"]
|
||||
path = core/deps/VulkanMemoryAllocator
|
||||
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||
[submodule "core/deps/glslang"]
|
||||
path = core/deps/glslang
|
||||
url = https://github.com/KhronosGroup/glslang.git
|
||||
[submodule "core/deps/volk"]
|
||||
path = core/deps/volk
|
||||
url = https://github.com/zeux/volk.git
|
||||
|
|
|
@ -17,7 +17,7 @@ option(USE_HOST_LIBZIP "Use host libzip" ON)
|
|||
option(USE_OPENMP "Use OpenMP if available" ON)
|
||||
option(USE_VULKAN "Build with Vulkan support" ON)
|
||||
option(LIBRETRO "Build libretro core" OFF)
|
||||
option(USE_OPENGL "Use Open GL API" ON)
|
||||
option(USE_OPENGL "Use OpenGL API" ON)
|
||||
option(USE_VIDEOCORE "RPI: use the legacy Broadcom GLES libraries" OFF)
|
||||
option(APPLE_BREAKPAD "macOS: Build breakpad client and dump symbols" OFF)
|
||||
|
||||
|
@ -293,6 +293,11 @@ target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm)
|
|||
|
||||
if(USE_VULKAN)
|
||||
option(BUILD_EXTERNAL "Build external dependencies in /External" OFF)
|
||||
option(SKIP_GLSLANG_INSTALL "Skip installation" ON)
|
||||
option(ENABLE_SPVREMAPPER "Enables building of SPVRemapper" OFF)
|
||||
option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" OFF)
|
||||
option(ENABLE_HLSL "Enables HLSL input support" OFF)
|
||||
option(ENABLE_PCH "Enables Precompiled header" OFF)
|
||||
add_subdirectory(core/deps/glslang EXCLUDE_FROM_ALL)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE SPIRV)
|
||||
endif()
|
||||
|
@ -1063,6 +1068,13 @@ if(NOT LIBRETRO)
|
|||
endif()
|
||||
|
||||
if(USE_VULKAN)
|
||||
add_subdirectory(core/deps/Vulkan-Headers)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Vulkan::Headers)
|
||||
|
||||
add_library(VulkanMemoryAllocator INTERFACE)
|
||||
target_include_directories(VulkanMemoryAllocator INTERFACE core/deps/VulkanMemoryAllocator/include)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE VulkanMemoryAllocator)
|
||||
|
||||
if(NOT LIBRETRO)
|
||||
if(ANDROID)
|
||||
set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_ANDROID_KHR)
|
||||
|
@ -1076,7 +1088,7 @@ if(USE_VULKAN)
|
|||
|
||||
set(VOLK_PULL_IN_VULKAN OFF)
|
||||
add_subdirectory(core/deps/volk)
|
||||
target_include_directories(volk PRIVATE core/khronos)
|
||||
target_include_directories(volk PRIVATE core/deps/Vulkan-Headers/include)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE volk)
|
||||
endif()
|
||||
|
||||
|
@ -1108,7 +1120,6 @@ if(USE_VULKAN)
|
|||
core/rend/vulkan/texture.cpp
|
||||
core/rend/vulkan/texture.h
|
||||
core/rend/vulkan/utils.h
|
||||
core/rend/vulkan/vk_mem_alloc.h
|
||||
core/rend/vulkan/vmallocator.cpp
|
||||
core/rend/vulkan/vmallocator.h
|
||||
core/rend/vulkan/overlay.cpp
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit c896e2f920273bfee852da9cca2a356bc1c2031e
|
|
@ -0,0 +1 @@
|
|||
Subproject commit a6bfc237255a6bac1513f7c1ebde6d8aed6b5191
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 10423ec659d301a0ff2daac8bbf38980abf27590
|
|
@ -1,108 +0,0 @@
|
|||
# Windows Build Configuration for AppVeyor
|
||||
# http://www.appveyor.com/docs/appveyor-yml
|
||||
|
||||
# build version format
|
||||
version: "{build}"
|
||||
|
||||
os: Visual Studio 2013
|
||||
|
||||
platform:
|
||||
- x64
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
# changes to these files don't need to trigger testing
|
||||
skip_commits:
|
||||
files:
|
||||
- README.md
|
||||
- README-spirv-remap.txt
|
||||
- LICENSE.txt
|
||||
- CODE_OF_CONDUCT.md
|
||||
- BUILD.*
|
||||
- WORKSPACE
|
||||
- kokoro/*
|
||||
- make-revision
|
||||
- Android.mk
|
||||
- _config.yml
|
||||
|
||||
# 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
|
||||
|
||||
matrix:
|
||||
fast_finish: true # Show final status immediately if a test fails.
|
||||
|
||||
# scripts that run after cloning repository
|
||||
install:
|
||||
- C:/Python27/python.exe update_glslang_sources.py
|
||||
- set PATH=C:\ninja;C:\Python36;%PATH%
|
||||
- git clone https://github.com/google/googletest.git External/googletest
|
||||
- cd External/googletest
|
||||
- git checkout 440527a61e1c91188195f7de212c63c77e8f0a45
|
||||
- cd ../..
|
||||
|
||||
build:
|
||||
parallel: true # enable MSBuild parallel builds
|
||||
verbosity: minimal
|
||||
|
||||
build_script:
|
||||
- mkdir build && cd build
|
||||
- cmake -G "Visual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=install ..
|
||||
- cmake --build . --config %CONFIGURATION% --target install
|
||||
|
||||
test_script:
|
||||
- ctest -C %CONFIGURATION% --output-on-failure
|
||||
- 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
|
||||
bin\spirv-remap.exe
|
||||
include\glslang\*
|
||||
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
|
|
@ -1,13 +0,0 @@
|
|||
Language: Cpp
|
||||
IndentWidth: 4
|
||||
PointerAlignment: Left
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping: { AfterFunction: true, AfterControlStatement: false }
|
||||
IndentCaseLabels: false
|
||||
ReflowComments: false
|
||||
ColumnLimit: 120
|
||||
AccessModifierOffset: -4
|
||||
AlignTrailingComments: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
|
@ -1,17 +0,0 @@
|
|||
# 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 eol=lf
|
||||
*.c text eol=lf
|
||||
*.cpp text eol=lf
|
||||
*.y text eol=lf
|
||||
*.out text eol=lf
|
||||
*.conf text eol=lf
|
||||
*.err text eol=lf
|
|
@ -1,10 +0,0 @@
|
|||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.exe
|
||||
tags
|
||||
TAGS
|
||||
build/
|
||||
Test/localResults/
|
||||
External/googletest
|
||||
External/spirv-tools
|
|
@ -1,128 +0,0 @@
|
|||
# Linux and Mac Build Configuration for Travis
|
||||
|
||||
language: cpp
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
# Use Ubuntu 14.04 LTS (Trusty) as the Linux testing environment.
|
||||
sudo: false
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: aGFrgzyKp+84hKrGkxVWg8cHV61uqrKEHT38gfSQK6+WS4GfLOyH83p7WnsEBb7AMhzU7LMNFdvOFr6+NaMpVnqRvc40CEG1Q+lNg9Pq9mhIZLowvDrfqTL9kQ+8Nbw5Q6/dg6CTvY7fvRfpfCEmKIUZBRkoKUuHeuM1uy3IupFcdNuL5bSYn3Beo+apSJginh9DI4BLDXFUgBzTRSLLyCX5g3cpaeGGOCr8quJlYx75W6HRck5g9SZuLtUoH9GFEV3l+ZEWB8noErW+J56L03bwNwFuuAh321evw++oQk5KFa8rlDvar3SJ3b1RHB8u/eq5DBYMyaK/fS8+Q7QbGr8diF/wDe68bKO7U9IhpNfExXmczCpExjHomW5TQv4rYdGhygPMfW97aIsPRYyNKcl4fkmb7NDrM8w0Jscdq2g5c2Kz0ItyZoBri/NXLwFQQjaVCs7Pf97TjuMA7mK0GJmDTRzi6SrDYlWMt5BQL3y0CCojyfLIRcTh0CQjQI29s97bLfQrYAxt9GNNFR+HTXRLLrkaAlJkPGEPwUywlSfEThnvHLesNxYqemolAYpQT4ithoL4GehGIHmaxsW295aKVhuRf8K9eBODNqrfblvM42UHhjntT+92ZnQ/Gkq80GqaMxnxi4PO5FyPIxt0r981b54YBkWi8YA4P7w5pNI=
|
||||
matrix:
|
||||
- GLSLANG_BUILD_TYPE=Release
|
||||
- GLSLANG_BUILD_TYPE=Debug
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
matrix:
|
||||
fast_finish: true # Show final status immediately if a test fails.
|
||||
exclude:
|
||||
# Skip GCC builds on Mac OS X.
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
include:
|
||||
# Additional build using Android NDK.
|
||||
- env: BUILD_NDK=ON
|
||||
|
||||
cache:
|
||||
apt: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
|
||||
install:
|
||||
# Make sure that clang-3.6 is selected on Linux.
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "clang" ]]; then
|
||||
export CC=clang-3.6 CXX=clang++-3.6;
|
||||
fi
|
||||
# Download a recent Android NDK and use its android.toolchain.cmake file.
|
||||
- if [[ "$BUILD_NDK" == "ON" ]]; then
|
||||
export ANDROID_NDK=$HOME/android-ndk;
|
||||
git init $ANDROID_NDK;
|
||||
pushd $ANDROID_NDK;
|
||||
git remote add dneto0 https://github.com/dneto0/android-ndk.git;
|
||||
git fetch --depth=1 dneto0 r17b-strip;
|
||||
git checkout FETCH_HEAD;
|
||||
popd;
|
||||
export TOOLCHAIN_PATH=$ANDROID_NDK/build/cmake/android.toolchain.cmake;
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- git clone --depth=1 https://github.com/google/googletest.git External/googletest
|
||||
- ./update_glslang_sources.py
|
||||
|
||||
script:
|
||||
- mkdir build && cd build
|
||||
# For Android, do release building using NDK without testing.
|
||||
# Use android-14, the oldest native API level supporeted by NDK r17b.
|
||||
# We can use newer API levels if we want.
|
||||
# For Linux and macOS, do debug/release building with testing.
|
||||
- if [[ "$BUILD_NDK" == "ON" ]]; then
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_PATH}
|
||||
-DANDROID_NATIVE_API_LEVEL=android-14
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DANDROID_ABI="armeabi-v7a with NEON"
|
||||
-DBUILD_TESTING=OFF ..;
|
||||
make -j4;
|
||||
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/*
|
||||
lib/libglslang${SUFFIX}.a
|
||||
lib/libHLSL${SUFFIX}.a
|
||||
lib/libOGLCompiler${SUFFIX}.a
|
||||
lib/libOSDependent${SUFFIX}.a
|
||||
lib/libSPIRV${SUFFIX}.a
|
||||
lib/libSPVRemapper${SUFFIX}.a
|
||||
lib/libSPIRV-Tools${SUFFIX}.a
|
||||
lib/libSPIRV-Tools-opt${SUFFIX}.a;
|
||||
fi
|
||||
|
||||
before_deploy:
|
||||
# Tag the current top of the tree as "master-tot".
|
||||
# Travis CI replies on the tag name to properly push to GitHub Releases.
|
||||
- git config --global user.name "Travis CI"
|
||||
- git config --global user.email "builds@travis-ci.org"
|
||||
- git tag -f master-tot
|
||||
- git push -q -f https://${glslangtoken}@github.com/KhronosGroup/glslang --tags
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key: ${glslangtoken}
|
||||
on:
|
||||
branch: master
|
||||
condition: ${CC} == clang* && ${BUILD_NDK} != ON
|
||||
file: ${TARBALL}
|
||||
skip_cleanup: true
|
||||
overwrite: true
|
|
@ -1,100 +0,0 @@
|
|||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
GLSLANG_OS_FLAGS := -DGLSLANG_OSINCLUDE_UNIX
|
||||
# AMD and NV extensions are turned on by default in upstream Glslang.
|
||||
GLSLANG_DEFINES:= -DAMD_EXTENSIONS -DNV_EXTENSIONS -DENABLE_HLSL $(GLSLANG_OS_FLAGS)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:=OSDependent
|
||||
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
|
||||
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES:=glslang/OSDependent/Unix/ossource.cpp
|
||||
LOCAL_C_INCLUDES:=$(LOCAL_PATH) $(LOCAL_PATH)/glslang/OSDependent/Unix/
|
||||
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/glslang/OSDependent/Unix/
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:=OGLCompiler
|
||||
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
|
||||
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES:=OGLCompilersDLL/InitializeDll.cpp
|
||||
LOCAL_C_INCLUDES:=$(LOCAL_PATH)/OGLCompiler
|
||||
LOCAL_STATIC_LIBRARIES:=OSDependent
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# Build Glslang's HLSL parser library.
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:=HLSL
|
||||
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
|
||||
LOCAL_SRC_FILES:= \
|
||||
hlsl/hlslAttributes.cpp \
|
||||
hlsl/hlslGrammar.cpp \
|
||||
hlsl/hlslOpMap.cpp \
|
||||
hlsl/hlslParseables.cpp \
|
||||
hlsl/hlslParseHelper.cpp \
|
||||
hlsl/hlslScanContext.cpp \
|
||||
hlsl/hlslTokenStream.cpp
|
||||
LOCAL_C_INCLUDES:=$(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/hlsl
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
GLSLANG_OUT_PATH=$(if $(call host-path-is-absolute,$(TARGET_OUT)),$(TARGET_OUT),$(abspath $(TARGET_OUT)))
|
||||
|
||||
LOCAL_MODULE:=glslang
|
||||
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
|
||||
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES:= \
|
||||
glslang/GenericCodeGen/CodeGen.cpp \
|
||||
glslang/GenericCodeGen/Link.cpp \
|
||||
glslang/MachineIndependent/attribute.cpp \
|
||||
glslang/MachineIndependent/Constant.cpp \
|
||||
glslang/MachineIndependent/glslang_tab.cpp \
|
||||
glslang/MachineIndependent/InfoSink.cpp \
|
||||
glslang/MachineIndependent/Initialize.cpp \
|
||||
glslang/MachineIndependent/Intermediate.cpp \
|
||||
glslang/MachineIndependent/intermOut.cpp \
|
||||
glslang/MachineIndependent/IntermTraverse.cpp \
|
||||
glslang/MachineIndependent/iomapper.cpp \
|
||||
glslang/MachineIndependent/limits.cpp \
|
||||
glslang/MachineIndependent/linkValidate.cpp \
|
||||
glslang/MachineIndependent/parseConst.cpp \
|
||||
glslang/MachineIndependent/ParseContextBase.cpp \
|
||||
glslang/MachineIndependent/ParseHelper.cpp \
|
||||
glslang/MachineIndependent/PoolAlloc.cpp \
|
||||
glslang/MachineIndependent/propagateNoContraction.cpp \
|
||||
glslang/MachineIndependent/reflection.cpp \
|
||||
glslang/MachineIndependent/RemoveTree.cpp \
|
||||
glslang/MachineIndependent/Scan.cpp \
|
||||
glslang/MachineIndependent/ShaderLang.cpp \
|
||||
glslang/MachineIndependent/SymbolTable.cpp \
|
||||
glslang/MachineIndependent/Versions.cpp \
|
||||
glslang/MachineIndependent/preprocessor/PpAtom.cpp \
|
||||
glslang/MachineIndependent/preprocessor/PpContext.cpp \
|
||||
glslang/MachineIndependent/preprocessor/Pp.cpp \
|
||||
glslang/MachineIndependent/preprocessor/PpScanner.cpp \
|
||||
glslang/MachineIndependent/preprocessor/PpTokens.cpp
|
||||
LOCAL_C_INCLUDES:=$(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/glslang/MachineIndependent \
|
||||
$(GLSLANG_OUT_PATH)
|
||||
LOCAL_STATIC_LIBRARIES:=OSDependent OGLCompiler HLSL
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:=SPIRV
|
||||
LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti -Werror $(GLSLANG_DEFINES)
|
||||
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)
|
||||
LOCAL_SRC_FILES:= \
|
||||
SPIRV/GlslangToSpv.cpp \
|
||||
SPIRV/InReadableOrder.cpp \
|
||||
SPIRV/Logger.cpp \
|
||||
SPIRV/SPVRemapper.cpp \
|
||||
SPIRV/SpvBuilder.cpp \
|
||||
SPIRV/SpvPostProcess.cpp \
|
||||
SPIRV/SpvTools.cpp \
|
||||
SPIRV/disassemble.cpp \
|
||||
SPIRV/doc.cpp
|
||||
LOCAL_C_INCLUDES:=$(LOCAL_PATH) $(LOCAL_PATH)/glslang/SPIRV
|
||||
LOCAL_EXPORT_C_INCLUDES:=$(LOCAL_PATH)/glslang/SPIRV
|
||||
LOCAL_STATIC_LIBRARIES:=glslang
|
||||
include $(BUILD_STATIC_LIBRARY)
|
|
@ -1,247 +0,0 @@
|
|||
package(
|
||||
default_visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# Description:
|
||||
#
|
||||
# Khronos reference front-end for GLSL and ESSL, and sample SPIR-V generator.
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
exports_files(["LICENSE"])
|
||||
|
||||
COMMON_COPTS = select({
|
||||
"@bazel_tools//src/conditions:windows": [""],
|
||||
"//conditions:default": [
|
||||
"-Wall",
|
||||
"-Wuninitialized",
|
||||
"-Wunused",
|
||||
"-Wunused-local-typedefs",
|
||||
"-Wunused-parameter",
|
||||
"-Wunused-value",
|
||||
"-Wunused-variable",
|
||||
"-Wno-reorder",
|
||||
"-std=c++11",
|
||||
"-fvisibility=hidden",
|
||||
"-fvisibility-inlines-hidden",
|
||||
"-fno-exceptions",
|
||||
"-fno-rtti",
|
||||
],
|
||||
})
|
||||
|
||||
cc_library(
|
||||
name = "glslang",
|
||||
srcs = glob(
|
||||
[
|
||||
"glslang/GenericCodeGen/*.cpp",
|
||||
"glslang/MachineIndependent/*.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/*.cpp",
|
||||
"hlsl/*.cpp",
|
||||
],
|
||||
exclude = [
|
||||
"glslang/MachineIndependent/pch.cpp",
|
||||
"glslang/MachineIndependent/pch.h",
|
||||
"hlsl/pch.cpp",
|
||||
"hlsl/pch.h",
|
||||
],
|
||||
) + [
|
||||
"OGLCompilersDLL/InitializeDll.cpp",
|
||||
] + select({
|
||||
"@bazel_tools//src/conditions:windows":
|
||||
["glslang/OSDependent/Windows/ossource.cpp"],
|
||||
"//conditions:default":
|
||||
["glslang/OSDependent/Unix/ossource.cpp"],
|
||||
}),
|
||||
hdrs = glob([
|
||||
"glslang/Include/*.h",
|
||||
"glslang/MachineIndependent/*.h",
|
||||
"glslang/MachineIndependent/preprocessor/*.h",
|
||||
"hlsl/*.h",
|
||||
]) + [
|
||||
"OGLCompilersDLL/InitializeDll.h",
|
||||
"StandAlone/DirStackFileIncluder.h",
|
||||
"glslang/OSDependent/osinclude.h",
|
||||
"glslang/Public/ShaderLang.h",
|
||||
],
|
||||
copts = COMMON_COPTS,
|
||||
defines = [
|
||||
"AMD_EXTENSIONS",
|
||||
"ENABLE_HLSL=0",
|
||||
"ENABLE_OPT=0",
|
||||
"NV_EXTENSIONS",
|
||||
],
|
||||
linkopts = select({
|
||||
"@bazel_tools//src/conditions:windows": [""],
|
||||
"//conditions:default": ["-lm", "-lpthread"],
|
||||
}),
|
||||
linkstatic = 1,
|
||||
)
|
||||
|
||||
genrule(
|
||||
name = "export_spirv_headers",
|
||||
srcs = [
|
||||
"SPIRV/GLSL.ext.AMD.h",
|
||||
"SPIRV/GLSL.ext.EXT.h",
|
||||
"SPIRV/GLSL.ext.KHR.h",
|
||||
"SPIRV/GLSL.ext.NV.h",
|
||||
"SPIRV/GLSL.std.450.h",
|
||||
"SPIRV/NonSemanticDebugPrintf.h",
|
||||
"SPIRV/spirv.hpp",
|
||||
],
|
||||
outs = [
|
||||
"include/SPIRV/GLSL.ext.AMD.h",
|
||||
"include/SPIRV/GLSL.ext.EXT.h",
|
||||
"include/SPIRV/GLSL.ext.KHR.h",
|
||||
"include/SPIRV/GLSL.ext.NV.h",
|
||||
"include/SPIRV/GLSL.std.450.h",
|
||||
"include/SPIRV/NonSemanticDebugPrintf.h",
|
||||
"include/SPIRV/spirv.hpp",
|
||||
],
|
||||
cmd = "mkdir -p $(@D)/include/SPIRV && cp $(SRCS) $(@D)/include/SPIRV/",
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "SPIRV_headers",
|
||||
hdrs = [":export_spirv_headers"],
|
||||
copts = COMMON_COPTS,
|
||||
includes = [
|
||||
"include",
|
||||
"include/SPIRV",
|
||||
],
|
||||
linkstatic = 1,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "SPIRV",
|
||||
srcs = glob(
|
||||
["SPIRV/*.cpp"],
|
||||
exclude = [
|
||||
"SPIRV/SpvTools.cpp",
|
||||
],
|
||||
),
|
||||
hdrs = [
|
||||
"SPIRV/GlslangToSpv.h",
|
||||
"SPIRV/Logger.h",
|
||||
"SPIRV/SPVRemapper.h",
|
||||
"SPIRV/SpvBuilder.h",
|
||||
"SPIRV/SpvTools.h",
|
||||
"SPIRV/bitutils.h",
|
||||
"SPIRV/disassemble.h",
|
||||
"SPIRV/doc.h",
|
||||
"SPIRV/hex_float.h",
|
||||
"SPIRV/spvIR.h",
|
||||
],
|
||||
copts = COMMON_COPTS,
|
||||
includes = ["SPIRV"],
|
||||
linkopts = select({
|
||||
"@bazel_tools//src/conditions:windows": [""],
|
||||
"//conditions:default": ["-lm"],
|
||||
}),
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
":SPIRV_headers",
|
||||
":glslang",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "glslang-default-resource-limits",
|
||||
srcs = ["StandAlone/ResourceLimits.cpp"],
|
||||
hdrs = ["StandAlone/ResourceLimits.h"],
|
||||
copts = COMMON_COPTS,
|
||||
linkstatic = 1,
|
||||
deps = [":glslang"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "glslangValidator",
|
||||
srcs = [
|
||||
"StandAlone/StandAlone.cpp",
|
||||
"StandAlone/Worklist.h",
|
||||
],
|
||||
copts = COMMON_COPTS,
|
||||
deps = [
|
||||
":SPIRV",
|
||||
":glslang",
|
||||
":glslang-default-resource-limits",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "spirv-remap",
|
||||
srcs = ["StandAlone/spirv-remap.cpp"],
|
||||
copts = COMMON_COPTS,
|
||||
deps = [
|
||||
":SPIRV",
|
||||
":glslang",
|
||||
":glslang-default-resource-limits",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "test_files",
|
||||
srcs = glob(
|
||||
["Test/**"],
|
||||
exclude = [
|
||||
"Test/bump",
|
||||
"Test/glslangValidator",
|
||||
"Test/runtests",
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "glslang_test_lib",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"gtests/HexFloat.cpp",
|
||||
"gtests/Initializer.h",
|
||||
"gtests/Settings.cpp",
|
||||
"gtests/Settings.h",
|
||||
"gtests/TestFixture.cpp",
|
||||
"gtests/TestFixture.h",
|
||||
"gtests/main.cpp",
|
||||
],
|
||||
copts = COMMON_COPTS,
|
||||
data = [":test_files"],
|
||||
defines = select({
|
||||
# Unfortunately we can't use $(location) in cc_library at the moment.
|
||||
# See https://github.com/bazelbuild/bazel/issues/1023
|
||||
# So we'll specify the path manually.
|
||||
"@bazel_tools//src/conditions:windows":
|
||||
["GLSLANG_TEST_DIRECTORY='\"../../../../../Test\"'"],
|
||||
"//conditions:default":
|
||||
["GLSLANG_TEST_DIRECTORY='\"Test\"'"],
|
||||
}),
|
||||
linkstatic = 1,
|
||||
deps = [
|
||||
":SPIRV",
|
||||
":glslang",
|
||||
":glslang-default-resource-limits",
|
||||
"@com_google_googletest//:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
GLSLANG_TESTS = glob(
|
||||
["gtests/*.FromFile.cpp"],
|
||||
# Since we are not building the SPIRV-Tools dependency, the following tests
|
||||
# cannot be performed.
|
||||
exclude = [
|
||||
"gtests/Hlsl.FromFile.cpp",
|
||||
"gtests/Spv.FromFile.cpp",
|
||||
],
|
||||
)
|
||||
|
||||
[cc_test(
|
||||
name = test_file.replace("gtests/", "").replace(".FromFile.cpp", "") + "_test",
|
||||
srcs = [test_file],
|
||||
copts = COMMON_COPTS,
|
||||
data = [
|
||||
":test_files",
|
||||
],
|
||||
deps = [
|
||||
":SPIRV",
|
||||
":glslang",
|
||||
":glslang_test_lib",
|
||||
],
|
||||
) for test_file in GLSLANG_TESTS]
|
|
@ -1,248 +0,0 @@
|
|||
# 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.
|
||||
|
||||
import("//build_overrides/glslang.gni")
|
||||
|
||||
# Both Chromium and Fuchsia use by default a set of warning errors
|
||||
# that is far too strict to compile this project. These are also
|
||||
# typically appended after |cflags|, overriding target-specific
|
||||
# definitions. To work around this, determine which configs to
|
||||
# add and remove in order to succesfully build the project.
|
||||
if (defined(is_fuchsia_tree) && is_fuchsia_tree) {
|
||||
_configs_to_remove = [ "//build/config:default_warnings" ]
|
||||
_configs_to_add = []
|
||||
} else {
|
||||
_configs_to_remove = [ "//build/config/compiler:chromium_code" ]
|
||||
_configs_to_add = [ "//build/config/compiler:no_chromium_code" ]
|
||||
}
|
||||
|
||||
spirv_tools_dir = glslang_spirv_tools_dir
|
||||
|
||||
config("glslang_public") {
|
||||
include_dirs = [ "." ]
|
||||
|
||||
defines = [ "ENABLE_HLSL=1" ]
|
||||
}
|
||||
|
||||
source_set("glslang_sources") {
|
||||
public_configs = [ ":glslang_public" ]
|
||||
|
||||
sources = [
|
||||
"OGLCompilersDLL/InitializeDll.cpp",
|
||||
"OGLCompilersDLL/InitializeDll.h",
|
||||
"SPIRV/GLSL.ext.AMD.h",
|
||||
"SPIRV/GLSL.ext.EXT.h",
|
||||
"SPIRV/GLSL.ext.KHR.h",
|
||||
"SPIRV/GLSL.ext.NV.h",
|
||||
"SPIRV/GLSL.std.450.h",
|
||||
"SPIRV/GlslangToSpv.cpp",
|
||||
"SPIRV/GlslangToSpv.h",
|
||||
"SPIRV/InReadableOrder.cpp",
|
||||
"SPIRV/Logger.cpp",
|
||||
"SPIRV/Logger.h",
|
||||
"SPIRV/NonSemanticDebugPrintf.h",
|
||||
"SPIRV/SPVRemapper.cpp",
|
||||
"SPIRV/SPVRemapper.h",
|
||||
"SPIRV/SpvBuilder.cpp",
|
||||
"SPIRV/SpvBuilder.h",
|
||||
"SPIRV/SpvPostProcess.cpp",
|
||||
"SPIRV/SpvTools.cpp",
|
||||
"SPIRV/SpvTools.h",
|
||||
"SPIRV/bitutils.h",
|
||||
"SPIRV/disassemble.cpp",
|
||||
"SPIRV/disassemble.h",
|
||||
"SPIRV/doc.cpp",
|
||||
"SPIRV/doc.h",
|
||||
"SPIRV/hex_float.h",
|
||||
"SPIRV/spirv.hpp",
|
||||
"SPIRV/spvIR.h",
|
||||
"glslang/GenericCodeGen/CodeGen.cpp",
|
||||
"glslang/GenericCodeGen/Link.cpp",
|
||||
"glslang/Include/BaseTypes.h",
|
||||
"glslang/Include/Common.h",
|
||||
"glslang/Include/ConstantUnion.h",
|
||||
"glslang/Include/InfoSink.h",
|
||||
"glslang/Include/InitializeGlobals.h",
|
||||
"glslang/Include/PoolAlloc.h",
|
||||
"glslang/Include/ResourceLimits.h",
|
||||
"glslang/Include/ShHandle.h",
|
||||
"glslang/Include/Types.h",
|
||||
"glslang/Include/arrays.h",
|
||||
"glslang/Include/intermediate.h",
|
||||
"glslang/Include/revision.h",
|
||||
"glslang/MachineIndependent/Constant.cpp",
|
||||
"glslang/MachineIndependent/InfoSink.cpp",
|
||||
"glslang/MachineIndependent/Initialize.cpp",
|
||||
"glslang/MachineIndependent/Initialize.h",
|
||||
"glslang/MachineIndependent/IntermTraverse.cpp",
|
||||
"glslang/MachineIndependent/Intermediate.cpp",
|
||||
"glslang/MachineIndependent/LiveTraverser.h",
|
||||
"glslang/MachineIndependent/ParseContextBase.cpp",
|
||||
"glslang/MachineIndependent/ParseHelper.cpp",
|
||||
"glslang/MachineIndependent/ParseHelper.h",
|
||||
"glslang/MachineIndependent/PoolAlloc.cpp",
|
||||
"glslang/MachineIndependent/RemoveTree.cpp",
|
||||
"glslang/MachineIndependent/RemoveTree.h",
|
||||
"glslang/MachineIndependent/Scan.cpp",
|
||||
"glslang/MachineIndependent/Scan.h",
|
||||
"glslang/MachineIndependent/ScanContext.h",
|
||||
"glslang/MachineIndependent/ShaderLang.cpp",
|
||||
"glslang/MachineIndependent/SymbolTable.cpp",
|
||||
"glslang/MachineIndependent/SymbolTable.h",
|
||||
"glslang/MachineIndependent/Versions.cpp",
|
||||
"glslang/MachineIndependent/Versions.h",
|
||||
"glslang/MachineIndependent/attribute.cpp",
|
||||
"glslang/MachineIndependent/attribute.h",
|
||||
"glslang/MachineIndependent/gl_types.h",
|
||||
"glslang/MachineIndependent/glslang_tab.cpp",
|
||||
"glslang/MachineIndependent/glslang_tab.cpp.h",
|
||||
"glslang/MachineIndependent/intermOut.cpp",
|
||||
"glslang/MachineIndependent/iomapper.cpp",
|
||||
"glslang/MachineIndependent/iomapper.h",
|
||||
"glslang/MachineIndependent/limits.cpp",
|
||||
"glslang/MachineIndependent/linkValidate.cpp",
|
||||
"glslang/MachineIndependent/localintermediate.h",
|
||||
"glslang/MachineIndependent/parseConst.cpp",
|
||||
"glslang/MachineIndependent/parseVersions.h",
|
||||
"glslang/MachineIndependent/preprocessor/Pp.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpAtom.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpContext.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpContext.h",
|
||||
"glslang/MachineIndependent/preprocessor/PpScanner.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpTokens.cpp",
|
||||
"glslang/MachineIndependent/preprocessor/PpTokens.h",
|
||||
"glslang/MachineIndependent/propagateNoContraction.cpp",
|
||||
"glslang/MachineIndependent/propagateNoContraction.h",
|
||||
"glslang/MachineIndependent/reflection.cpp",
|
||||
"glslang/MachineIndependent/reflection.h",
|
||||
"glslang/OSDependent/osinclude.h",
|
||||
"glslang/Public/ShaderLang.h",
|
||||
"hlsl/hlslAttributes.cpp",
|
||||
"hlsl/hlslAttributes.h",
|
||||
"hlsl/hlslGrammar.cpp",
|
||||
"hlsl/hlslGrammar.h",
|
||||
"hlsl/hlslOpMap.cpp",
|
||||
"hlsl/hlslOpMap.h",
|
||||
"hlsl/hlslParseHelper.cpp",
|
||||
"hlsl/hlslParseHelper.h",
|
||||
"hlsl/hlslParseables.cpp",
|
||||
"hlsl/hlslParseables.h",
|
||||
"hlsl/hlslScanContext.cpp",
|
||||
"hlsl/hlslScanContext.h",
|
||||
"hlsl/hlslTokenStream.cpp",
|
||||
"hlsl/hlslTokenStream.h",
|
||||
"hlsl/hlslTokens.h",
|
||||
]
|
||||
|
||||
defines = [ "ENABLE_OPT=1" ]
|
||||
|
||||
if (is_win) {
|
||||
sources += [ "glslang/OSDependent/Windows/ossource.cpp" ]
|
||||
defines += [ "GLSLANG_OSINCLUDE_WIN32" ]
|
||||
} else {
|
||||
sources += [ "glslang/OSDependent/Unix/ossource.cpp" ]
|
||||
defines += [ "GLSLANG_OSINCLUDE_UNIX" ]
|
||||
}
|
||||
|
||||
if (is_clang) {
|
||||
cflags = [
|
||||
"-Wno-extra-semi",
|
||||
"-Wno-ignored-qualifiers",
|
||||
"-Wno-implicit-fallthrough",
|
||||
"-Wno-inconsistent-missing-override",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-unused-variable",
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wno-newline-eof",
|
||||
]
|
||||
}
|
||||
if (is_win && !is_clang) {
|
||||
cflags = [
|
||||
"/wd4018", # signed/unsigned mismatch
|
||||
"/wd4189", # local variable is initialized but not referenced
|
||||
]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"${spirv_tools_dir}:spvtools_opt",
|
||||
"${spirv_tools_dir}:spvtools_val",
|
||||
]
|
||||
|
||||
configs -= _configs_to_remove
|
||||
configs += _configs_to_add
|
||||
}
|
||||
|
||||
source_set("glslang_default_resource_limits_sources") {
|
||||
sources = [
|
||||
"StandAlone/ResourceLimits.cpp",
|
||||
"StandAlone/ResourceLimits.h",
|
||||
]
|
||||
deps = [
|
||||
":glslang_sources",
|
||||
]
|
||||
public_configs = [ ":glslang_public" ]
|
||||
|
||||
configs -= _configs_to_remove
|
||||
configs += _configs_to_add
|
||||
}
|
||||
|
||||
executable("glslang_validator") {
|
||||
sources = [
|
||||
"StandAlone/DirStackFileIncluder.h",
|
||||
"StandAlone/StandAlone.cpp",
|
||||
]
|
||||
if (!is_win) {
|
||||
cflags = [ "-Woverflow" ]
|
||||
}
|
||||
defines = [ "ENABLE_OPT=1" ]
|
||||
deps = [
|
||||
":glslang_default_resource_limits_sources",
|
||||
":glslang_sources",
|
||||
]
|
||||
|
||||
configs -= _configs_to_remove
|
||||
configs += _configs_to_add
|
||||
}
|
||||
|
||||
executable("spirv-remap") {
|
||||
sources = [
|
||||
"StandAlone/spirv-remap.cpp",
|
||||
]
|
||||
defines = [ "ENABLE_OPT=1" ]
|
||||
deps = [
|
||||
":glslang_sources",
|
||||
]
|
||||
|
||||
configs -= _configs_to_remove
|
||||
configs += _configs_to_add
|
||||
}
|
|
@ -1,229 +0,0 @@
|
|||
# increase to 3.1 once all major distributions
|
||||
# include a version of CMake >= 3.1
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 NEW)
|
||||
endif()
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# Enable compile commands database
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Adhere to GNU filesystem layout conventions
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Needed for CMAKE_DEPENDENT_OPTION macro
|
||||
include(CMakeDependentOption)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
|
||||
option(BUILD_EXTERNAL "Build external dependencies in /External" ON)
|
||||
|
||||
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_SPVREMAPPER "Enables building of SPVRemapper" ON)
|
||||
|
||||
option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON)
|
||||
|
||||
option(ENABLE_GLSLANG_JS
|
||||
"If using Emscripten, build glslang.js. Otherwise, builds a sample executable for binary-size testing." OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_GLSLANG_WEBMIN
|
||||
"Reduces glslang to minimum needed for web use"
|
||||
OFF "ENABLE_GLSLANG_JS"
|
||||
OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_GLSLANG_WEBMIN_DEVEL
|
||||
"For ENABLE_GLSLANG_WEBMIN builds, enables compilation error messages"
|
||||
OFF "ENABLE_GLSLANG_WEBMIN"
|
||||
OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_EMSCRIPTEN_SINGLE_FILE
|
||||
"If using Emscripten, enables SINGLE_FILE build"
|
||||
OFF "ENABLE_GLSLANG_JS AND EMSCRIPTEN"
|
||||
OFF)
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_EMSCRIPTEN_ENVIRONMENT_NODE
|
||||
"If using Emscripten, builds to run on Node instead of Web"
|
||||
OFF "ENABLE_GLSLANG_JS AND EMSCRIPTEN"
|
||||
OFF)
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(ENABLE_HLSL
|
||||
"Enables HLSL input support"
|
||||
ON "NOT ENABLE_GLSLANG_WEBMIN"
|
||||
OFF)
|
||||
|
||||
option(ENABLE_RTTI "Enables RTTI" OFF)
|
||||
option(ENABLE_OPT "Enables spirv-opt capability if present" ON)
|
||||
option(ENABLE_PCH "Enables Precompiled header" ON)
|
||||
option(ENABLE_CTEST "Enables testing" ON)
|
||||
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND WIN32)
|
||||
set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "..." FORCE)
|
||||
endif()
|
||||
|
||||
option(USE_CCACHE "Use ccache" OFF)
|
||||
if(USE_CCACHE)
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
endif(CCACHE_FOUND)
|
||||
endif()
|
||||
|
||||
# Precompiled header macro. Parameters are source file list and filename for pch cpp file.
|
||||
macro(glslang_pch SRCS PCHCPP)
|
||||
if(MSVC AND CMAKE_GENERATOR MATCHES "^Visual Studio" AND NOT ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" AND ENABLE_PCH)
|
||||
set(PCH_NAME "$(IntDir)\\pch.pch")
|
||||
# make source files use/depend on PCH_NAME
|
||||
set_source_files_properties(${${SRCS}} PROPERTIES COMPILE_FLAGS "/Yupch.h /FIpch.h /Fp${PCH_NAME} /Zm300" OBJECT_DEPENDS "${PCH_NAME}")
|
||||
# make PCHCPP file compile and generate PCH_NAME
|
||||
set_source_files_properties(${PCHCPP} PROPERTIES COMPILE_FLAGS "/Ycpch.h /Fp${PCH_NAME} /Zm300" OBJECT_OUTPUTS "${PCH_NAME}")
|
||||
list(APPEND ${SRCS} "${PCHCPP}")
|
||||
endif()
|
||||
endmacro(glslang_pch)
|
||||
|
||||
project(glslang)
|
||||
|
||||
if(ENABLE_CTEST)
|
||||
include(CTest)
|
||||
endif()
|
||||
|
||||
if(ENABLE_HLSL)
|
||||
add_definitions(-DENABLE_HLSL)
|
||||
endif(ENABLE_HLSL)
|
||||
|
||||
if(ENABLE_GLSLANG_WEBMIN)
|
||||
add_definitions(-DGLSLANG_WEB)
|
||||
if(ENABLE_GLSLANG_WEBMIN_DEVEL)
|
||||
add_definitions(-DGLSLANG_WEB_DEVEL)
|
||||
endif(ENABLE_GLSLANG_WEBMIN_DEVEL)
|
||||
endif(ENABLE_GLSLANG_WEBMIN)
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_DEBUG_POSTFIX "d")
|
||||
if(MSVC)
|
||||
include(ChooseMSVCCRT.cmake)
|
||||
endif(MSVC)
|
||||
add_definitions(-DGLSLANG_OSINCLUDE_WIN32)
|
||||
elseif(UNIX)
|
||||
add_definitions(-DGLSLANG_OSINCLUDE_UNIX)
|
||||
else(WIN32)
|
||||
message("unknown platform")
|
||||
endif(WIN32)
|
||||
|
||||
if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
|
||||
add_compile_options(-Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs
|
||||
-Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable -fno-exceptions)
|
||||
add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over.
|
||||
if(NOT ENABLE_RTTI)
|
||||
add_compile_options(-fno-rtti)
|
||||
endif()
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0")
|
||||
add_compile_options(-Werror=deprecated-copy)
|
||||
endif()
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" AND NOT MSVC)
|
||||
add_compile_options(-Wall -Wuninitialized -Wunused -Wunused-local-typedefs
|
||||
-Wunused-parameter -Wunused-value -Wunused-variable)
|
||||
add_compile_options(-Wno-reorder) # disable this from -Wall, since it happens all over.
|
||||
if(NOT ENABLE_RTTI)
|
||||
add_compile_options(-fno-rtti)
|
||||
endif()
|
||||
elseif(MSVC)
|
||||
if(NOT ENABLE_RTTI)
|
||||
add_compile_options(/GR-) # Disable RTTI
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_GLSLANG_JS)
|
||||
if(MSVC)
|
||||
add_compile_options(/Os /GR-)
|
||||
else()
|
||||
add_compile_options(-Os -fno-exceptions)
|
||||
if(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang" AND NOT MSVC)
|
||||
add_compile_options(-Wno-unused-parameter)
|
||||
add_compile_options(-Wno-unused-variable -Wno-unused-const-variable)
|
||||
endif()
|
||||
endif()
|
||||
endif(ENABLE_GLSLANG_JS)
|
||||
|
||||
# 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
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
else()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
endif()
|
||||
|
||||
function(glslang_set_link_args TARGET)
|
||||
# For MinGW compiles, statically link against the GCC and C++ runtimes.
|
||||
# This avoids the need to ship those runtimes as DLLs.
|
||||
if(WIN32 AND ${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
|
||||
set_target_properties(${TARGET} PROPERTIES
|
||||
LINK_FLAGS "-static -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
endfunction(glslang_set_link_args)
|
||||
|
||||
# CMake needs to find the right version of python, right from the beginning,
|
||||
# otherwise, it will find the wrong version and fail later
|
||||
if(BUILD_EXTERNAL AND IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/External)
|
||||
find_package(PythonInterp 3 REQUIRED)
|
||||
|
||||
# We depend on these for later projects, so they should come first.
|
||||
add_subdirectory(External)
|
||||
endif()
|
||||
|
||||
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(OGLCompilersDLL)
|
||||
if(ENABLE_GLSLANG_BINARIES)
|
||||
add_subdirectory(StandAlone)
|
||||
endif()
|
||||
add_subdirectory(SPIRV)
|
||||
if(ENABLE_HLSL)
|
||||
add_subdirectory(hlsl)
|
||||
endif(ENABLE_HLSL)
|
||||
if(ENABLE_CTEST)
|
||||
add_subdirectory(gtests)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
# glslang-testsuite runs a bash script on Windows.
|
||||
# Make sure to use '-o igncr' flag to ignore carriage returns (\r).
|
||||
set(IGNORE_CR_FLAG "")
|
||||
if(WIN32)
|
||||
set(IGNORE_CR_FLAG -o igncr)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CONFIGURATION_TYPES)
|
||||
set(RESULTS_PATH ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>/localResults)
|
||||
set(VALIDATOR_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/$<CONFIGURATION>/glslangValidator)
|
||||
set(REMAP_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/$<CONFIGURATION>/spirv-remap)
|
||||
else(CMAKE_CONFIGURATION_TYPES)
|
||||
set(RESULTS_PATH ${CMAKE_CURRENT_BINARY_DIR}/localResults)
|
||||
set(VALIDATOR_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/glslangValidator)
|
||||
set(REMAP_PATH ${CMAKE_CURRENT_BINARY_DIR}/StandAlone/spirv-remap)
|
||||
endif(CMAKE_CONFIGURATION_TYPES)
|
||||
|
||||
add_test(NAME glslang-testsuite
|
||||
COMMAND bash ${IGNORE_CR_FLAG} runtests ${RESULTS_PATH} ${VALIDATOR_PATH} ${REMAP_PATH}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Test/)
|
||||
endif(BUILD_TESTING)
|
|
@ -1 +0,0 @@
|
|||
A reminder that this issue tracker is managed by the Khronos Group. Interactions here should follow the Khronos Code of Conduct (https://www.khronos.org/developers/code-of-conduct), which prohibits aggressive or derogatory language. Please keep the discussion friendly and civil.
|
|
@ -1,105 +0,0 @@
|
|||
# The macro choose_msvc_crt() takes a list of possible
|
||||
# C runtimes to choose from, in the form of compiler flags,
|
||||
# to present to the user. (MTd for /MTd, etc)
|
||||
#
|
||||
# The macro is invoked at the end of the file.
|
||||
#
|
||||
# CMake already sets CRT flags in the CMAKE_CXX_FLAGS_* and
|
||||
# CMAKE_C_FLAGS_* variables by default. To let the user
|
||||
# override that for each build type:
|
||||
# 1. Detect which CRT is already selected, and reflect this in
|
||||
# LLVM_USE_CRT_* so the user can have a better idea of what
|
||||
# changes they're making.
|
||||
# 2. Replace the flags in both variables with the new flag via a regex.
|
||||
# 3. set() the variables back into the cache so the changes
|
||||
# are user-visible.
|
||||
|
||||
### Helper macros: ###
|
||||
macro(make_crt_regex regex crts)
|
||||
set(${regex} "")
|
||||
foreach(crt ${${crts}})
|
||||
# Trying to match the beginning or end of the string with stuff
|
||||
# like [ ^]+ didn't work, so use a bunch of parentheses instead.
|
||||
set(${regex} "${${regex}}|(^| +)/${crt}($| +)")
|
||||
endforeach(crt)
|
||||
string(REGEX REPLACE "^\\|" "" ${regex} "${${regex}}")
|
||||
endmacro(make_crt_regex)
|
||||
|
||||
macro(get_current_crt crt_current regex flagsvar)
|
||||
# Find the selected-by-CMake CRT for each build type, if any.
|
||||
# Strip off the leading slash and any whitespace.
|
||||
string(REGEX MATCH "${${regex}}" ${crt_current} "${${flagsvar}}")
|
||||
string(REPLACE "/" " " ${crt_current} "${${crt_current}}")
|
||||
string(STRIP "${${crt_current}}" ${crt_current})
|
||||
endmacro(get_current_crt)
|
||||
|
||||
# Replaces or adds a flag to a variable.
|
||||
# Expects 'flag' to be padded with spaces.
|
||||
macro(set_flag_in_var flagsvar regex flag)
|
||||
string(REGEX MATCH "${${regex}}" current_flag "${${flagsvar}}")
|
||||
if("${current_flag}" STREQUAL "")
|
||||
set(${flagsvar} "${${flagsvar}}${${flag}}")
|
||||
else()
|
||||
string(REGEX REPLACE "${${regex}}" "${${flag}}" ${flagsvar} "${${flagsvar}}")
|
||||
endif()
|
||||
string(STRIP "${${flagsvar}}" ${flagsvar})
|
||||
# Make sure this change gets reflected in the cache/gui.
|
||||
# CMake requires the docstring parameter whenever set() touches the cache,
|
||||
# so get the existing docstring and re-use that.
|
||||
get_property(flagsvar_docs CACHE ${flagsvar} PROPERTY HELPSTRING)
|
||||
set(${flagsvar} "${${flagsvar}}" CACHE STRING "${flagsvar_docs}" FORCE)
|
||||
endmacro(set_flag_in_var)
|
||||
|
||||
|
||||
macro(choose_msvc_crt MSVC_CRT)
|
||||
if(LLVM_USE_CRT)
|
||||
message(FATAL_ERROR
|
||||
"LLVM_USE_CRT is deprecated. Use the CMAKE_BUILD_TYPE-specific
|
||||
variables (LLVM_USE_CRT_DEBUG, etc) instead.")
|
||||
endif()
|
||||
|
||||
make_crt_regex(MSVC_CRT_REGEX ${MSVC_CRT})
|
||||
|
||||
foreach(build_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE})
|
||||
string(TOUPPER "${build_type}" build)
|
||||
if (NOT LLVM_USE_CRT_${build})
|
||||
get_current_crt(LLVM_USE_CRT_${build}
|
||||
MSVC_CRT_REGEX
|
||||
CMAKE_CXX_FLAGS_${build})
|
||||
set(LLVM_USE_CRT_${build}
|
||||
"${LLVM_USE_CRT_${build}}"
|
||||
CACHE STRING "Specify VC++ CRT to use for ${build_type} configurations."
|
||||
FORCE)
|
||||
set_property(CACHE LLVM_USE_CRT_${build}
|
||||
PROPERTY STRINGS ;${${MSVC_CRT}})
|
||||
endif(NOT LLVM_USE_CRT_${build})
|
||||
endforeach(build_type)
|
||||
|
||||
foreach(build_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE})
|
||||
string(TOUPPER "${build_type}" build)
|
||||
if ("${LLVM_USE_CRT_${build}}" STREQUAL "")
|
||||
set(flag_string " ")
|
||||
else()
|
||||
set(flag_string " /${LLVM_USE_CRT_${build}} ")
|
||||
list(FIND ${MSVC_CRT} ${LLVM_USE_CRT_${build}} idx)
|
||||
if (idx LESS 0)
|
||||
message(FATAL_ERROR
|
||||
"Invalid value for LLVM_USE_CRT_${build}: ${LLVM_USE_CRT_${build}}. Valid options are one of: ${${MSVC_CRT}}")
|
||||
endif (idx LESS 0)
|
||||
message(STATUS "Using ${build_type} VC++ CRT: ${LLVM_USE_CRT_${build}}")
|
||||
endif()
|
||||
foreach(lang C CXX)
|
||||
set_flag_in_var(CMAKE_${lang}_FLAGS_${build} MSVC_CRT_REGEX flag_string)
|
||||
endforeach(lang)
|
||||
endforeach(build_type)
|
||||
endmacro(choose_msvc_crt MSVC_CRT)
|
||||
|
||||
|
||||
# List of valid CRTs for MSVC
|
||||
set(MSVC_CRT
|
||||
MD
|
||||
MDd
|
||||
MT
|
||||
MTd)
|
||||
|
||||
choose_msvc_crt(MSVC_CRT)
|
|
@ -1,44 +0,0 @@
|
|||
# Suppress all warnings from external projects.
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS -w)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
if(TARGET gmock)
|
||||
message(STATUS "Google Mock already configured - use it")
|
||||
elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
|
||||
# We need to make sure Google Test does not mess up with the
|
||||
# global CRT settings on Windows.
|
||||
if(WIN32)
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
endif(WIN32)
|
||||
# EXCLUDE_FROM_ALL keeps the install target from installing GTEST files.
|
||||
add_subdirectory(googletest EXCLUDE_FROM_ALL)
|
||||
set(GTEST_TARGETS
|
||||
gtest
|
||||
gtest_main
|
||||
gmock
|
||||
gmock_main)
|
||||
foreach(target ${GTEST_TARGETS})
|
||||
set_property(TARGET ${target} PROPERTY FOLDER gtest)
|
||||
endforeach()
|
||||
mark_as_advanced(gmock_build_tests
|
||||
BUILD_GMOCK
|
||||
BUILD_GTEST
|
||||
BUILD_SHARED_LIBS
|
||||
gtest_build_samples
|
||||
gtest_build_tests
|
||||
gtest_disable_pthreads
|
||||
gtest_force_shared_crt
|
||||
gtest_hide_internal_symbols)
|
||||
else()
|
||||
message(STATUS
|
||||
"Google Mock was not found - tests based on that will not build")
|
||||
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()
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
Here, glslang proper means core GLSL parsing, HLSL parsing, and SPIR-V code
|
||||
generation. Glslang proper requires use of two licenses, one that covers
|
||||
non-preprocessing and an additional one that covers preprocessing.
|
||||
|
||||
Bison was removed long ago. You can build glslang from the source grammar,
|
||||
using tools of your choice, without using bison or any bison files.
|
||||
|
||||
Other parts, outside of glslang proper, include:
|
||||
|
||||
- gl_types.h, only needed for OpenGL-like reflection, and can be left out of
|
||||
a parse and codegen project. See it for its license.
|
||||
|
||||
- update_glslang_sources.py, which is not part of the project proper and does
|
||||
not need to be used.
|
||||
|
||||
- the SPIR-V "remapper", which is optional, but has the same license as
|
||||
glslang proper
|
||||
|
||||
- Google tests and SPIR-V tools, and anything in the external subdirectory
|
||||
are external and optional; see them for their respective licenses.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The core of glslang-proper, minus the preprocessor is licenced as follows:
|
||||
|
||||
//
|
||||
// Copyright (C) 2015-2018 Google, Inc.
|
||||
// Copyright (C) <various other dates and companies>
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The preprocessor has the core license stated above, plus an additional licence:
|
||||
|
||||
/****************************************************************************\
|
||||
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.
|
||||
\****************************************************************************/
|
|
@ -1,15 +0,0 @@
|
|||
set(SOURCES InitializeDll.cpp InitializeDll.h)
|
||||
|
||||
add_library(OGLCompiler STATIC ${SOURCES})
|
||||
set_property(TARGET OGLCompiler PROPERTY FOLDER glslang)
|
||||
set_property(TARGET OGLCompiler PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if(WIN32)
|
||||
source_group("Source" FILES ${SOURCES})
|
||||
endif(WIN32)
|
||||
|
||||
if(ENABLE_GLSLANG_INSTALL)
|
||||
install(TARGETS OGLCompiler EXPORT OGLCompilerTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(EXPORT OGLCompilerTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
|
@ -1,165 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// 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.
|
||||
//
|
||||
|
||||
#define SH_EXPORTING
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "InitializeDll.h"
|
||||
#include "../glslang/Include/InitializeGlobals.h"
|
||||
#include "../glslang/Public/ShaderLang.h"
|
||||
#include "../glslang/Include/PoolAlloc.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
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()
|
||||
{
|
||||
glslang::GetGlobalLock();
|
||||
|
||||
if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
|
||||
//
|
||||
// Function is re-entrant.
|
||||
//
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
return true;
|
||||
}
|
||||
|
||||
ThreadInitializeIndex = OS_AllocTLSIndex();
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! InitializePoolIndex()) {
|
||||
assert(0 && "InitProcess(): Failed to initialize global pool");
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! InitThread()) {
|
||||
assert(0 && "InitProcess(): Failed to initialize thread");
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
return false;
|
||||
}
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
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()
|
||||
{
|
||||
//
|
||||
// This function is re-entrant
|
||||
//
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
|
||||
assert(0 && "InitThread(): Process hasn't been initalised.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
|
||||
return true;
|
||||
|
||||
if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
||||
assert(0 && "InitThread(): Unable to set init flag.");
|
||||
return false;
|
||||
}
|
||||
|
||||
glslang::SetThreadPoolAllocator(nullptr);
|
||||
|
||||
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 success = true;
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||
return true;
|
||||
|
||||
//
|
||||
// Function is re-entrant and this thread may not have been initialized.
|
||||
//
|
||||
if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
|
||||
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
|
||||
assert(0 && "DetachThread(): Unable to clear init flag.");
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
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 success = true;
|
||||
|
||||
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||
return true;
|
||||
|
||||
success = DetachThread();
|
||||
|
||||
OS_FreeTLSIndex(ThreadInitializeIndex);
|
||||
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
|
@ -1,49 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
|
||||
// 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 __INITIALIZEDLL_H
|
||||
#define __INITIALIZEDLL_H
|
||||
|
||||
#include "../glslang/OSDependent/osinclude.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
bool InitProcess();
|
||||
bool InitThread();
|
||||
bool DetachThread(); // not called from standalone, perhaps other tools rely on parts of it
|
||||
bool DetachProcess(); // not called from standalone, perhaps other tools rely on parts of it
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // __INITIALIZEDLL_H
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
|
||||
VERSION
|
||||
--------------------------------------------------------------------------------
|
||||
spirv-remap 0.97
|
||||
|
||||
INTRO:
|
||||
--------------------------------------------------------------------------------
|
||||
spirv-remap is a utility to improve compression of SPIR-V binary files via
|
||||
entropy reduction, plus optional stripping of debug information and
|
||||
load/store optimization. It transforms SPIR-V to SPIR-V, remapping IDs. The
|
||||
resulting modules have an increased ID range (IDs are not as tightly packed
|
||||
around zero), but will compress better when multiple modules are compressed
|
||||
together, since compressor's dictionary can find better cross module
|
||||
commonality.
|
||||
|
||||
Remapping is accomplished via canonicalization. Thus, modules can be
|
||||
compressed one at a time with no loss of quality relative to operating on
|
||||
many modules at once. The command line tool operates on multiple modules
|
||||
only in the trivial repetition sense, for ease of use. The remapper API
|
||||
only accepts a single module at a time.
|
||||
|
||||
There are two modes of use: command line, and a C++11 API. Both are
|
||||
described below.
|
||||
|
||||
spirv-remap is currently in an alpha state. Although there are no known
|
||||
remapping defects, it has only been exercised on one real world game shader
|
||||
workload.
|
||||
|
||||
|
||||
FEEDBACK
|
||||
--------------------------------------------------------------------------------
|
||||
Report defects, enhancements requests, code improvements, etc to:
|
||||
spvremapper@lunarg.com
|
||||
|
||||
|
||||
COMMAND LINE USAGE:
|
||||
--------------------------------------------------------------------------------
|
||||
Examples are given with a verbosity of one (-v), but more verbosity can be
|
||||
had via -vv, -vvv, etc, or an integer parameter to --verbose, such as
|
||||
"--verbose 4". With no verbosity, the command is silent and returns 0 on
|
||||
success, and a positive integer error on failure.
|
||||
|
||||
Pre-built binaries for several OSs are available. Examples presented are
|
||||
for Linux. Command line arguments can be provided in any order.
|
||||
|
||||
1. Basic ID remapping
|
||||
|
||||
Perform ID remapping on all shaders in "*.spv", writing new files with
|
||||
the same basenames to /tmp/out_dir.
|
||||
|
||||
spirv-remap -v --map all --input *.spv --output /tmp/out_dir
|
||||
|
||||
2. Perform all possible size reductions
|
||||
|
||||
spirv-remap-linux-64 -v --do-everything --input *.spv --output /tmp/out_dir
|
||||
|
||||
Note that --do-everything is a synonym for:
|
||||
|
||||
--map all --dce all --opt all --strip all
|
||||
|
||||
API USAGE:
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
The public interface to the remapper is defined in SPIRV/SPVRemapper.h as follows:
|
||||
|
||||
namespace spv {
|
||||
|
||||
class spirvbin_t
|
||||
{
|
||||
public:
|
||||
enum Options { ... };
|
||||
spirvbin_t(int verbose = 0); // construct
|
||||
|
||||
// remap an existing binary in memory
|
||||
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// Type for error/log handler functions
|
||||
typedef std::function<void(const std::string&)> errorfn_t;
|
||||
typedef std::function<void(const std::string&)> logfn_t;
|
||||
|
||||
// Register error/log handling functions (can be c/c++ fn, lambda fn, or functor)
|
||||
static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
|
||||
static void registerLogHandler(logfn_t handler) { logHandler = handler; }
|
||||
};
|
||||
|
||||
} // namespace spv
|
||||
|
||||
The class definition is in SPVRemapper.cpp.
|
||||
|
||||
remap() accepts an std::vector of SPIR-V words, modifies them per the
|
||||
request given in 'opts', and leaves the 'spv' container with the result.
|
||||
It is safe to instantiate one spirvbin_t per thread and process a different
|
||||
SPIR-V in each.
|
||||
|
||||
The "opts" parameter to remap() accepts a bit mask of desired remapping
|
||||
options. See REMAPPING AND OPTIMIZATION OPTIONS.
|
||||
|
||||
On error, the function supplied to registerErrorHandler() will be invoked.
|
||||
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
|
||||
member, so need only be set up once, not once per spirvbin_t instance.
|
||||
|
||||
Log messages are supplied to registerLogHandler(). By default, log
|
||||
messages are eaten silently. The log handler is also a static member.
|
||||
|
||||
BUILD DEPENDENCIES:
|
||||
--------------------------------------------------------------------------------
|
||||
1. C++11 compatible compiler
|
||||
2. cmake
|
||||
3. glslang
|
||||
|
||||
|
||||
BUILDING
|
||||
--------------------------------------------------------------------------------
|
||||
The standalone remapper is built along side glslangValidator through its
|
||||
normal build process.
|
||||
|
||||
|
||||
REMAPPING AND OPTIMIZATION OPTIONS
|
||||
--------------------------------------------------------------------------------
|
||||
API:
|
||||
These are bits defined under spv::spirvbin_t::, and can be
|
||||
bitwise or-ed together as desired.
|
||||
|
||||
MAP_TYPES = canonicalize type IDs
|
||||
MAP_NAMES = canonicalize named data
|
||||
MAP_FUNCS = canonicalize function bodies
|
||||
DCE_FUNCS = remove dead functions
|
||||
DCE_VARS = remove dead variables
|
||||
DCE_TYPES = remove dead types
|
||||
OPT_LOADSTORE = optimize unneeded load/stores
|
||||
MAP_ALL = (MAP_TYPES | MAP_NAMES | MAP_FUNCS)
|
||||
DCE_ALL = (DCE_FUNCS | DCE_VARS | DCE_TYPES)
|
||||
OPT_ALL = (OPT_LOADSTORE)
|
||||
ALL_BUT_STRIP = (MAP_ALL | DCE_ALL | OPT_ALL)
|
||||
DO_EVERYTHING = (STRIP | ALL_BUT_STRIP)
|
||||
|
|
@ -1,442 +0,0 @@
|
|||
# News
|
||||
|
||||
[](https://travis-ci.org/KhronosGroup/glslang)
|
||||
[](https://ci.appveyor.com/project/Khronoswebmaster/glslang/branch/master)
|
||||
|
||||
## Planned Deprecations/Removals
|
||||
|
||||
1. **SPIRV Folder, 1-May, 2020.** Glslang, when installed through CMake,
|
||||
will install a `SPIRV` folder into `${CMAKE_INSTALL_INCLUDEDIR}`.
|
||||
This `SPIRV` folder is being moved to `glslang/SPIRV`.
|
||||
During the transition the `SPIRV` folder will be installed into both locations.
|
||||
The old install of `SPIRV/` will be removed as a CMake install target no sooner than May 1, 2020.
|
||||
See issue #1964.
|
||||
|
||||
2. **Visual Studio 2013, 20-July, 2020.** Keeping code compiling for MS Visual Studio 2013 will no longer be
|
||||
a goal as of July 20, 2020, the fifth anniversary of the release of Visual Studio 2015.
|
||||
|
||||
# Glslang Components and Status
|
||||
|
||||
There are several components:
|
||||
|
||||
### Reference Validator and GLSL/ESSL -> AST Front End
|
||||
|
||||
An OpenGL GLSL and OpenGL|ES GLSL (ESSL) front-end for reference validation and translation of GLSL/ESSL into an internal abstract syntax tree (AST).
|
||||
|
||||
**Status**: Virtually complete, with results carrying similar weight as the specifications.
|
||||
|
||||
### HLSL -> AST Front End
|
||||
|
||||
An HLSL front-end for translation of an approximation of HLSL to glslang's AST form.
|
||||
|
||||
**Status**: Partially complete. Semantics are not reference quality and input is not validated.
|
||||
This is in contrast to the [DXC project](https://github.com/Microsoft/DirectXShaderCompiler), which receives a much larger investment and attempts to have definitive/reference-level semantics.
|
||||
|
||||
See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
|
||||
|
||||
### AST -> SPIR-V Back End
|
||||
|
||||
Translates glslang's AST to the Khronos-specified SPIR-V intermediate language.
|
||||
|
||||
**Status**: Virtually complete.
|
||||
|
||||
### Reflector
|
||||
|
||||
An API for getting reflection information from the AST, reflection types/variables/etc. from the HLL source (not the SPIR-V).
|
||||
|
||||
**Status**: There is a large amount of functionality present, but no specification/goal to measure completeness against. It is accurate for the input HLL and AST, but only approximate for what would later be emitted for SPIR-V.
|
||||
|
||||
### Standalone Wrapper
|
||||
|
||||
`glslangValidator` is command-line tool for accessing the functionality above.
|
||||
|
||||
Status: Complete.
|
||||
|
||||
Tasks waiting to be done are documented as GitHub issues.
|
||||
|
||||
## Other References
|
||||
|
||||
Also see the Khronos landing page for glslang as a reference front end:
|
||||
|
||||
https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
|
||||
|
||||
The above page, while not kept up to date, includes additional information regarding glslang as a reference validator.
|
||||
|
||||
# How to Use Glslang
|
||||
|
||||
## Execution of Standalone Wrapper
|
||||
|
||||
To use the standalone binary form, execute `glslangValidator`, and it will print
|
||||
a usage statement. Basic operation is to give it a file containing a shader,
|
||||
and it will print out warnings/errors and optionally an AST.
|
||||
|
||||
The applied stage-specific rules are based on the file extension:
|
||||
* `.vert` for a vertex shader
|
||||
* `.tesc` for a tessellation control shader
|
||||
* `.tese` for a tessellation evaluation shader
|
||||
* `.geom` for a geometry shader
|
||||
* `.frag` for a fragment shader
|
||||
* `.comp` for a compute shader
|
||||
|
||||
There is also a non-shader extension
|
||||
* `.conf` for a configuration file of limits, see usage statement for example
|
||||
|
||||
## 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
|
||||
|
||||
* A C++11 compiler.
|
||||
(For MSVS: 2015 is recommended, 2013 is fully supported/tested, and 2010 support is attempted, but not tested.)
|
||||
* [CMake][cmake]: for generating compilation targets.
|
||||
* make: _Linux_, ninja is an alternative, if configured.
|
||||
* [Python 3.x][python]: for executing SPIRV-Tools scripts. (Optional if not using SPIRV-Tools and the 'External' subdirectory does not exist.)
|
||||
* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
|
||||
* [googletest][googletest]: _optional_, but should use if making any changes to glslang.
|
||||
|
||||
### Build steps
|
||||
|
||||
The following steps assume a Bash shell. On Windows, that could be the Git Bash
|
||||
shell or some other shell of your choosing.
|
||||
|
||||
#### 1) Check-Out this project
|
||||
|
||||
```bash
|
||||
cd <parent of where you want glslang to be>
|
||||
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
|
||||
```
|
||||
|
||||
If you want to use googletest with Visual Studio 2013, you also need to check out an older version:
|
||||
|
||||
```bash
|
||||
# to use googletest with Visual Studio 2013
|
||||
cd External/googletest
|
||||
git checkout 440527a61e1c91188195f7de212c63c77e8f0a45
|
||||
cd ../..
|
||||
```
|
||||
|
||||
If you wish to assure that SPIR-V generated from HLSL is legal for Vulkan,
|
||||
wish to invoke -Os to reduce SPIR-V size from HLSL or GLSL, or wish to run the
|
||||
integrated test suite, install spirv-tools with this:
|
||||
|
||||
```bash
|
||||
./update_glslang_sources.py
|
||||
```
|
||||
|
||||
#### 3) Configure
|
||||
|
||||
Assume the source directory is `$SOURCE_DIR` and the build directory is
|
||||
`$BUILD_DIR`. First ensure the build directory exists, then navigate to it:
|
||||
|
||||
```bash
|
||||
mkdir -p $BUILD_DIR
|
||||
cd $BUILD_DIR
|
||||
```
|
||||
|
||||
For building on Linux:
|
||||
|
||||
```bash
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/install" $SOURCE_DIR
|
||||
# "Release" (for CMAKE_BUILD_TYPE) could also be "Debug" or "RelWithDebInfo"
|
||||
```
|
||||
|
||||
For building on Android:
|
||||
```bash
|
||||
cmake $SOURCE_DIR -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$(pwd)/install" -DANDROID_ABI=arm64-v8a -DCMAKE_BUILD_TYPE=Release -DANDROID_STL=c++_static -DANDROID_PLATFORM=android-24 -DCMAKE_SYSTEM_NAME=Android -DANDROID_TOOLCHAIN=clang -DANDROID_ARM_MODE=arm -DCMAKE_MAKE_PROGRAM=$ANDROID_NDK_ROOT/prebuilt/linux-x86_64/bin/make -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake
|
||||
# If on Windows will be -DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make.exe
|
||||
# -G is needed for building on Windows
|
||||
# -DANDROID_ABI can also be armeabi-v7a for 32 bit
|
||||
```
|
||||
|
||||
For building on Windows:
|
||||
|
||||
```bash
|
||||
cmake $SOURCE_DIR -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
|
||||
# The CMAKE_INSTALL_PREFIX part is for testing (explained later).
|
||||
```
|
||||
|
||||
The CMake GUI also works for Windows (version 3.4.1 tested).
|
||||
|
||||
Also, consider using `git config --global core.fileMode false` (or with `--local`) on Windows
|
||||
to prevent the addition of execution permission on files.
|
||||
|
||||
#### 4) Build and Install
|
||||
|
||||
```bash
|
||||
# for Linux:
|
||||
make -j4 install
|
||||
|
||||
# for Windows:
|
||||
cmake --build . --config Release --target install
|
||||
# "Release" (for --config) could also be "Debug", "MinSizeRel", or "RelWithDebInfo"
|
||||
```
|
||||
|
||||
If using MSVC, after running CMake to configure, use the
|
||||
Configuration Manager to check the `INSTALL` project.
|
||||
|
||||
### If you need to change the GLSL grammar
|
||||
|
||||
The grammar in `glslang/MachineIndependent/glslang.y` has to be recompiled with
|
||||
bison if it changes, the output files are committed to the repo to avoid every
|
||||
developer needing to have bison configured to compile the project when grammar
|
||||
changes are quite infrequent. For windows you can get binaries from
|
||||
[GnuWin32][bison-gnu-win32].
|
||||
|
||||
The command to rebuild is:
|
||||
|
||||
```bash
|
||||
m4 -P MachineIndependent/glslang.m4 > MachineIndependent/glslang.y
|
||||
bison --defines=MachineIndependent/glslang_tab.cpp.h
|
||||
-t MachineIndependent/glslang.y
|
||||
-o MachineIndependent/glslang_tab.cpp
|
||||
```
|
||||
|
||||
The above commands are also available in the bash script in `updateGrammar`,
|
||||
when executed from the glslang subdirectory of the glslang repository.
|
||||
With no arguments it builds the full grammar, and with a "web" argument,
|
||||
the web grammar subset (see more about the web subset in the next section).
|
||||
|
||||
### Building to WASM for the Web and Node
|
||||
### Building a standalone JS/WASM library for the Web and Node
|
||||
|
||||
Use the steps in [Build Steps](#build-steps), with the following notes/exceptions:
|
||||
* `emsdk` needs to be present in your executable search path, *PATH* for
|
||||
Bash-like environments:
|
||||
+ [Instructions located here](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install)
|
||||
* Wrap cmake call: `emcmake cmake`
|
||||
* Set `-DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF`.
|
||||
* Set `-DENABLE_HLSL=OFF` if HLSL is not needed.
|
||||
* For a standalone JS/WASM library, turn on `-DENABLE_GLSLANG_JS=ON`.
|
||||
* For building a minimum-size web subset of core glslang:
|
||||
+ turn on `-DENABLE_GLSLANG_WEBMIN=ON` (disables HLSL)
|
||||
+ execute `updateGrammar web` from the glslang subdirectory
|
||||
(or if using your own scripts, `m4` needs a `-DGLSLANG_WEB` argument)
|
||||
+ optionally, for GLSL compilation error messages, turn on
|
||||
`-DENABLE_GLSLANG_WEBMIN_DEVEL=ON`
|
||||
* To get a fully minimized build, make sure to use `brotli` to compress the .js
|
||||
and .wasm files
|
||||
|
||||
Example:
|
||||
|
||||
```sh
|
||||
emcmake cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_GLSLANG_JS=ON \
|
||||
-DENABLE_HLSL=OFF -DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF ..
|
||||
```
|
||||
|
||||
## Building glslang - Using vcpkg
|
||||
|
||||
You can download and install glslang using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install glslang
|
||||
|
||||
The glslang port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
## Testing
|
||||
|
||||
Right now, there are two test harnesses existing in glslang: one is [Google
|
||||
Test](gtests/), one is the [`runtests` script](Test/runtests). The former
|
||||
runs unit tests and single-shader single-threaded integration tests, while
|
||||
the latter runs multiple-shader linking tests and multi-threaded tests.
|
||||
|
||||
### Running tests
|
||||
|
||||
The [`runtests` script](Test/runtests) requires compiled binaries to be
|
||||
installed into `$BUILD_DIR/install`. Please make sure you have supplied the
|
||||
correct configuration to CMake (using `-DCMAKE_INSTALL_PREFIX`) when building;
|
||||
otherwise, you may want to modify the path in the `runtests` script.
|
||||
|
||||
Running Google Test-backed tests:
|
||||
|
||||
```bash
|
||||
cd $BUILD_DIR
|
||||
|
||||
# for Linux:
|
||||
ctest
|
||||
|
||||
# for Windows:
|
||||
ctest -C {Debug|Release|RelWithDebInfo|MinSizeRel}
|
||||
|
||||
# or, run the test binary directly
|
||||
# (which gives more fine-grained control like filtering):
|
||||
<dir-to-glslangtests-in-build-dir>/glslangtests
|
||||
```
|
||||
|
||||
Running `runtests` script-backed tests:
|
||||
|
||||
```bash
|
||||
cd $SOURCE_DIR/Test && ./runtests
|
||||
```
|
||||
|
||||
If some tests fail with validation errors, there may be a mismatch between the
|
||||
version of `spirv-val` on the system and the version of glslang. In this
|
||||
case, it is necessary to run `update_glslang_sources.py`. See "Check-Out
|
||||
External Projects" above for more details.
|
||||
|
||||
### Contributing tests
|
||||
|
||||
Test results should always be included with a pull request that modifies
|
||||
functionality.
|
||||
|
||||
If you are writing unit tests, please use the Google Test framework and
|
||||
place the tests under the `gtests/` directory.
|
||||
|
||||
Integration tests are placed in the `Test/` directory. It contains test input
|
||||
and a subdirectory `baseResults/` that contains the expected results of the
|
||||
tests. Both the tests and `baseResults/` are under source-code control.
|
||||
|
||||
Google Test runs those integration tests by reading the test input, compiling
|
||||
them, and then compare against the expected results in `baseResults/`. The
|
||||
integration tests to run via Google Test is registered in various
|
||||
`gtests/*.FromFile.cpp` source files. `glslangtests` provides a command-line
|
||||
option `--update-mode`, which, if supplied, will overwrite the golden files
|
||||
under the `baseResults/` directory with real output from that invocation.
|
||||
For more information, please check `gtests/` directory's
|
||||
[README](gtests/README.md).
|
||||
|
||||
For the `runtests` script, it will generate current results in the
|
||||
`localResults/` directory and `diff` them against the `baseResults/`.
|
||||
When you want to update the tracked test results, they need to be
|
||||
copied from `localResults/` to `baseResults/`. This can be done by
|
||||
the `bump` shell script.
|
||||
|
||||
You can add your own private list of tests, not tracked publicly, by using
|
||||
`localtestlist` to list non-tracked tests. This is automatically read
|
||||
by `runtests` and included in the `diff` and `bump` process.
|
||||
|
||||
## Programmatic Interfaces
|
||||
|
||||
Another piece of software can programmatically translate shaders to an AST
|
||||
using one of two different interfaces:
|
||||
* A new C++ class-oriented interface, or
|
||||
* The original C functional interface
|
||||
|
||||
The `main()` in `StandAlone/StandAlone.cpp` shows examples using both styles.
|
||||
|
||||
### C++ Class Interface (new, preferred)
|
||||
|
||||
This interface is in roughly the last 1/3 of `ShaderLang.h`. It is in the
|
||||
glslang namespace and contains the following, here with suggested calls
|
||||
for generating SPIR-V:
|
||||
|
||||
```cxx
|
||||
const char* GetEsslVersionString();
|
||||
const char* GetGlslVersionString();
|
||||
bool InitializeProcess();
|
||||
void FinalizeProcess();
|
||||
|
||||
class TShader
|
||||
setStrings(...);
|
||||
setEnvInput(EShSourceHlsl or EShSourceGlsl, stage, EShClientVulkan or EShClientOpenGL, 100);
|
||||
setEnvClient(EShClientVulkan or EShClientOpenGL, EShTargetVulkan_1_0 or EShTargetVulkan_1_1 or EShTargetOpenGL_450);
|
||||
setEnvTarget(EShTargetSpv, EShTargetSpv_1_0 or EShTargetSpv_1_3);
|
||||
bool parse(...);
|
||||
const char* getInfoLog();
|
||||
|
||||
class TProgram
|
||||
void addShader(...);
|
||||
bool link(...);
|
||||
const char* getInfoLog();
|
||||
Reflection queries
|
||||
```
|
||||
|
||||
For just validating (not generating code), substitute these calls:
|
||||
|
||||
```cxx
|
||||
setEnvInput(EShSourceHlsl or EShSourceGlsl, stage, EShClientNone, 0);
|
||||
setEnvClient(EShClientNone, 0);
|
||||
setEnvTarget(EShTargetNone, 0);
|
||||
```
|
||||
|
||||
See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
|
||||
details. There is a block comment giving more detail above the calls for
|
||||
`setEnvInput, setEnvClient, and setEnvTarget`.
|
||||
|
||||
### C Functional Interface (original)
|
||||
|
||||
This interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to
|
||||
as the `Sh*()` interface, as all the entry points start `Sh`.
|
||||
|
||||
The `Sh*()` interface takes a "compiler" call-back object, which it calls after
|
||||
building call back that is passed the AST and can then execute a back end on it.
|
||||
|
||||
The following is a simplified resulting run-time call stack:
|
||||
|
||||
```c
|
||||
ShCompile(shader, compiler) -> compiler(AST) -> <back end>
|
||||
```
|
||||
|
||||
In practice, `ShCompile()` takes shader strings, default version, and
|
||||
warning/error and other options for controlling compilation.
|
||||
|
||||
## Basic Internal Operation
|
||||
|
||||
* Initial lexical analysis is done by the preprocessor in
|
||||
`MachineIndependent/Preprocessor`, and then refined by a GLSL scanner
|
||||
in `MachineIndependent/Scan.cpp`. There is currently no use of flex.
|
||||
|
||||
* Code is parsed using bison on `MachineIndependent/glslang.y` with the
|
||||
aid of a symbol table and an AST. The symbol table is not passed on to
|
||||
the back-end; the intermediate representation stands on its own.
|
||||
The tree is built by the grammar productions, many of which are
|
||||
offloaded into `ParseHelper.cpp`, and by `Intermediate.cpp`.
|
||||
|
||||
* The intermediate representation is very high-level, and represented
|
||||
as an in-memory tree. This serves to lose no information from the
|
||||
original program, and to have efficient transfer of the result from
|
||||
parsing to the back-end. In the AST, constants are propagated and
|
||||
folded, and a very small amount of dead code is eliminated.
|
||||
|
||||
To aid linking and reflection, the last top-level branch in the AST
|
||||
lists all global symbols.
|
||||
|
||||
* The primary algorithm of the back-end compiler is to traverse the
|
||||
tree (high-level intermediate representation), and create an internal
|
||||
object code representation. There is an example of how to do this
|
||||
in `MachineIndependent/intermOut.cpp`.
|
||||
|
||||
* Reduction of the tree to a linear byte-code style low-level intermediate
|
||||
representation is likely a good way to generate fully optimized code.
|
||||
|
||||
* There is currently some dead old-style linker-type code still lying around.
|
||||
|
||||
* Memory pool: parsing uses types derived from C++ `std` types, using a
|
||||
custom allocator that puts them in a memory pool. This makes allocation
|
||||
of individual container/contents just few cycles and deallocation free.
|
||||
This pool is popped after the AST is made and processed.
|
||||
|
||||
The use is simple: if you are going to call `new`, there are three cases:
|
||||
|
||||
- the object comes from the pool (its base class has the macro
|
||||
`POOL_ALLOCATOR_NEW_DELETE` in it) and you do not have to call `delete`
|
||||
|
||||
- it is a `TString`, in which case call `NewPoolTString()`, which gets
|
||||
it from the pool, and there is no corresponding `delete`
|
||||
|
||||
- the object does not come from the pool, and you have to do normal
|
||||
C++ memory management of what you `new`
|
||||
|
||||
* Features can be protected by version/extension/stage/profile:
|
||||
See the comment in `glslang/MachineIndependent/Versions.cpp`.
|
||||
|
||||
[cmake]: https://cmake.org/
|
||||
[python]: https://www.python.org/
|
||||
[bison]: https://www.gnu.org/software/bison/
|
||||
[googletest]: https://github.com/google/googletest
|
||||
[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
|
||||
[master-tot-release]: https://github.com/KhronosGroup/glslang/releases/tag/master-tot
|
|
@ -1,103 +0,0 @@
|
|||
set(SOURCES
|
||||
GlslangToSpv.cpp
|
||||
InReadableOrder.cpp
|
||||
Logger.cpp
|
||||
SpvBuilder.cpp
|
||||
SpvPostProcess.cpp
|
||||
doc.cpp
|
||||
SpvTools.cpp
|
||||
disassemble.cpp)
|
||||
|
||||
set(SPVREMAP_SOURCES
|
||||
SPVRemapper.cpp
|
||||
doc.cpp)
|
||||
|
||||
set(HEADERS
|
||||
bitutils.h
|
||||
spirv.hpp
|
||||
GLSL.std.450.h
|
||||
GLSL.ext.EXT.h
|
||||
GLSL.ext.KHR.h
|
||||
GlslangToSpv.h
|
||||
hex_float.h
|
||||
Logger.h
|
||||
SpvBuilder.h
|
||||
spvIR.h
|
||||
doc.h
|
||||
SpvTools.h
|
||||
disassemble.h
|
||||
GLSL.ext.AMD.h
|
||||
GLSL.ext.NV.h
|
||||
NonSemanticDebugPrintf.h)
|
||||
|
||||
set(SPVREMAP_HEADERS
|
||||
SPVRemapper.h
|
||||
doc.h)
|
||||
|
||||
add_library(SPIRV ${LIB_TYPE} ${SOURCES} ${HEADERS})
|
||||
set_property(TARGET SPIRV PROPERTY FOLDER glslang)
|
||||
set_property(TARGET SPIRV PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
target_include_directories(SPIRV PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
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)
|
||||
endif()
|
||||
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
set_target_properties(SPIRV PROPERTIES PREFIX "")
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
set_target_properties(SPVRemapper PROPERTIES PREFIX "")
|
||||
endif()
|
||||
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)
|
||||
target_include_directories(SPIRV PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../External>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/External>)
|
||||
else()
|
||||
target_link_libraries(SPIRV glslang)
|
||||
endif(ENABLE_OPT)
|
||||
|
||||
if(WIN32)
|
||||
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
||||
source_group("Source" FILES ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||
endif(WIN32)
|
||||
|
||||
if(ENABLE_GLSLANG_INSTALL)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
install(TARGETS SPVRemapper EXPORT SPVRemapperTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
install(TARGETS SPIRV EXPORT SPIRVTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
else()
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
install(TARGETS SPVRemapper EXPORT SPVRemapperTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
install(TARGETS SPIRV EXPORT SPIRVTargets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
if (ENABLE_SPVREMAPPER)
|
||||
install(EXPORT SPVRemapperTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
endif()
|
||||
|
||||
install(EXPORT SPIRVTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
|
||||
install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SPIRV/)
|
||||
install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/glslang/SPIRV/)
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
** 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
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
** 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 = 2;
|
||||
|
||||
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";
|
||||
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
|
||||
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
|
||||
|
||||
#endif // #ifndef GLSLextEXT_H
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
** Copyright (c) 2014-2020 The Khronos Group Inc.
|
||||
** Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||
**
|
||||
** 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_8bit_storage = "SPV_KHR_8bit_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";
|
||||
static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model";
|
||||
static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physical_storage_buffer";
|
||||
static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer";
|
||||
static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
|
||||
static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock";
|
||||
static const char* const E_SPV_KHR_non_semantic_info = "SPV_KHR_non_semantic_info";
|
||||
static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_tracing";
|
||||
static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
|
||||
#endif // #ifndef GLSLextKHR_H
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
** 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 = 11;
|
||||
|
||||
//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";
|
||||
|
||||
//SPV_NV_fragment_shader_barycentric
|
||||
const char* const E_SPV_NV_fragment_shader_barycentric = "SPV_NV_fragment_shader_barycentric";
|
||||
|
||||
//SPV_NV_compute_shader_derivatives
|
||||
const char* const E_SPV_NV_compute_shader_derivatives = "SPV_NV_compute_shader_derivatives";
|
||||
|
||||
//SPV_NV_shader_image_footprint
|
||||
const char* const E_SPV_NV_shader_image_footprint = "SPV_NV_shader_image_footprint";
|
||||
|
||||
//SPV_NV_mesh_shader
|
||||
const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
|
||||
|
||||
//SPV_NV_raytracing
|
||||
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
|
||||
|
||||
//SPV_NV_shading_rate
|
||||
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
|
||||
|
||||
//SPV_NV_cooperative_matrix
|
||||
const char* const E_SPV_NV_cooperative_matrix = "SPV_NV_cooperative_matrix";
|
||||
|
||||
//SPV_NV_shader_sm_builtins
|
||||
const char* const E_SPV_NV_shader_sm_builtins = "SPV_NV_shader_sm_builtins";
|
||||
|
||||
#endif // #ifndef GLSLextNV_H
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
** 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 GLSLstd450_H
|
||||
#define GLSLstd450_H
|
||||
|
||||
static const int GLSLstd450Version = 100;
|
||||
static const int GLSLstd450Revision = 1;
|
||||
|
||||
enum GLSLstd450 {
|
||||
GLSLstd450Bad = 0, // Don't use
|
||||
|
||||
GLSLstd450Round = 1,
|
||||
GLSLstd450RoundEven = 2,
|
||||
GLSLstd450Trunc = 3,
|
||||
GLSLstd450FAbs = 4,
|
||||
GLSLstd450SAbs = 5,
|
||||
GLSLstd450FSign = 6,
|
||||
GLSLstd450SSign = 7,
|
||||
GLSLstd450Floor = 8,
|
||||
GLSLstd450Ceil = 9,
|
||||
GLSLstd450Fract = 10,
|
||||
|
||||
GLSLstd450Radians = 11,
|
||||
GLSLstd450Degrees = 12,
|
||||
GLSLstd450Sin = 13,
|
||||
GLSLstd450Cos = 14,
|
||||
GLSLstd450Tan = 15,
|
||||
GLSLstd450Asin = 16,
|
||||
GLSLstd450Acos = 17,
|
||||
GLSLstd450Atan = 18,
|
||||
GLSLstd450Sinh = 19,
|
||||
GLSLstd450Cosh = 20,
|
||||
GLSLstd450Tanh = 21,
|
||||
GLSLstd450Asinh = 22,
|
||||
GLSLstd450Acosh = 23,
|
||||
GLSLstd450Atanh = 24,
|
||||
GLSLstd450Atan2 = 25,
|
||||
|
||||
GLSLstd450Pow = 26,
|
||||
GLSLstd450Exp = 27,
|
||||
GLSLstd450Log = 28,
|
||||
GLSLstd450Exp2 = 29,
|
||||
GLSLstd450Log2 = 30,
|
||||
GLSLstd450Sqrt = 31,
|
||||
GLSLstd450InverseSqrt = 32,
|
||||
|
||||
GLSLstd450Determinant = 33,
|
||||
GLSLstd450MatrixInverse = 34,
|
||||
|
||||
GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
|
||||
GLSLstd450ModfStruct = 36, // no OpVariable operand
|
||||
GLSLstd450FMin = 37,
|
||||
GLSLstd450UMin = 38,
|
||||
GLSLstd450SMin = 39,
|
||||
GLSLstd450FMax = 40,
|
||||
GLSLstd450UMax = 41,
|
||||
GLSLstd450SMax = 42,
|
||||
GLSLstd450FClamp = 43,
|
||||
GLSLstd450UClamp = 44,
|
||||
GLSLstd450SClamp = 45,
|
||||
GLSLstd450FMix = 46,
|
||||
GLSLstd450IMix = 47, // Reserved
|
||||
GLSLstd450Step = 48,
|
||||
GLSLstd450SmoothStep = 49,
|
||||
|
||||
GLSLstd450Fma = 50,
|
||||
GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
|
||||
GLSLstd450FrexpStruct = 52, // no OpVariable operand
|
||||
GLSLstd450Ldexp = 53,
|
||||
|
||||
GLSLstd450PackSnorm4x8 = 54,
|
||||
GLSLstd450PackUnorm4x8 = 55,
|
||||
GLSLstd450PackSnorm2x16 = 56,
|
||||
GLSLstd450PackUnorm2x16 = 57,
|
||||
GLSLstd450PackHalf2x16 = 58,
|
||||
GLSLstd450PackDouble2x32 = 59,
|
||||
GLSLstd450UnpackSnorm2x16 = 60,
|
||||
GLSLstd450UnpackUnorm2x16 = 61,
|
||||
GLSLstd450UnpackHalf2x16 = 62,
|
||||
GLSLstd450UnpackSnorm4x8 = 63,
|
||||
GLSLstd450UnpackUnorm4x8 = 64,
|
||||
GLSLstd450UnpackDouble2x32 = 65,
|
||||
|
||||
GLSLstd450Length = 66,
|
||||
GLSLstd450Distance = 67,
|
||||
GLSLstd450Cross = 68,
|
||||
GLSLstd450Normalize = 69,
|
||||
GLSLstd450FaceForward = 70,
|
||||
GLSLstd450Reflect = 71,
|
||||
GLSLstd450Refract = 72,
|
||||
|
||||
GLSLstd450FindILsb = 73,
|
||||
GLSLstd450FindSMsb = 74,
|
||||
GLSLstd450FindUMsb = 75,
|
||||
|
||||
GLSLstd450InterpolateAtCentroid = 76,
|
||||
GLSLstd450InterpolateAtSample = 77,
|
||||
GLSLstd450InterpolateAtOffset = 78,
|
||||
|
||||
GLSLstd450NMin = 79,
|
||||
GLSLstd450NMax = 80,
|
||||
GLSLstd450NClamp = 81,
|
||||
|
||||
GLSLstd450Count
|
||||
};
|
||||
|
||||
#endif // #ifndef GLSLstd450_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,61 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014 LunarG, Inc.
|
||||
// Copyright (C) 2015-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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
#pragma warning(disable : 4464) // relative include path contains '..'
|
||||
#endif
|
||||
|
||||
#include "SpvTools.h"
|
||||
#include "glslang/Include/intermediate.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
void GetSpirvVersion(std::string&);
|
||||
int GetSpirvGeneratorVersion();
|
||||
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 OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
||||
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
|
||||
// The SPIR-V spec requires code blocks to appear in an order satisfying the
|
||||
// dominator-tree direction (ie, dominator before the dominated). This is,
|
||||
// actually, easy to achieve: any pre-order CFG traversal algorithm will do it.
|
||||
// Because such algorithms visit a block only after traversing some path to it
|
||||
// from the root, they necessarily visit the block's idom first.
|
||||
//
|
||||
// But not every graph-traversal algorithm outputs blocks in an order that
|
||||
// appears logical to human readers. The problem is that unrelated branches may
|
||||
// be interspersed with each other, and merge blocks may come before some of the
|
||||
// branches being merged.
|
||||
//
|
||||
// A good, human-readable order of blocks may be achieved by performing
|
||||
// depth-first search but delaying merge nodes until after all their branches
|
||||
// have been visited. This is implemented below by the inReadableOrder()
|
||||
// function.
|
||||
|
||||
#include "spvIR.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_set>
|
||||
|
||||
using spv::Block;
|
||||
using spv::Id;
|
||||
|
||||
namespace {
|
||||
// Traverses CFG in a readable order, invoking a pre-set callback on each block.
|
||||
// Use by calling visit() on the root block.
|
||||
class ReadableOrderTraverser {
|
||||
public:
|
||||
ReadableOrderTraverser(std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||
: callback_(callback) {}
|
||||
// Visits the block if it hasn't been visited already and isn't currently
|
||||
// being delayed. Invokes callback(block, why, header), then descends into its
|
||||
// successors. Delays merge-block and continue-block processing until all
|
||||
// the branches have been completed. If |block| is an unreachable merge block or
|
||||
// an unreachable continue target, then |header| is the corresponding header block.
|
||||
void visit(Block* block, spv::ReachReason why, Block* header)
|
||||
{
|
||||
assert(block);
|
||||
if (why == spv::ReachViaControlFlow) {
|
||||
reachableViaControlFlow_.insert(block);
|
||||
}
|
||||
if (visited_.count(block) || delayed_.count(block))
|
||||
return;
|
||||
callback_(block, why, header);
|
||||
visited_.insert(block);
|
||||
Block* mergeBlock = nullptr;
|
||||
Block* continueBlock = nullptr;
|
||||
auto mergeInst = block->getMergeInstruction();
|
||||
if (mergeInst) {
|
||||
Id mergeId = mergeInst->getIdOperand(0);
|
||||
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
|
||||
delayed_.insert(mergeBlock);
|
||||
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
|
||||
Id continueId = mergeInst->getIdOperand(1);
|
||||
continueBlock =
|
||||
block->getParent().getParent().getInstruction(continueId)->getBlock();
|
||||
delayed_.insert(continueBlock);
|
||||
}
|
||||
}
|
||||
if (why == spv::ReachViaControlFlow) {
|
||||
const auto& successors = block->getSuccessors();
|
||||
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
||||
visit(*it, why, nullptr);
|
||||
}
|
||||
if (continueBlock) {
|
||||
const spv::ReachReason continueWhy =
|
||||
(reachableViaControlFlow_.count(continueBlock) > 0)
|
||||
? spv::ReachViaControlFlow
|
||||
: spv::ReachDeadContinue;
|
||||
delayed_.erase(continueBlock);
|
||||
visit(continueBlock, continueWhy, block);
|
||||
}
|
||||
if (mergeBlock) {
|
||||
const spv::ReachReason mergeWhy =
|
||||
(reachableViaControlFlow_.count(mergeBlock) > 0)
|
||||
? spv::ReachViaControlFlow
|
||||
: spv::ReachDeadMerge;
|
||||
delayed_.erase(mergeBlock);
|
||||
visit(mergeBlock, mergeWhy, block);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void(Block*, spv::ReachReason, Block*)> callback_;
|
||||
// Whether a block has already been visited or is being delayed.
|
||||
std::unordered_set<Block *> visited_, delayed_;
|
||||
|
||||
// The set of blocks that actually are reached via control flow.
|
||||
std::unordered_set<Block *> reachableViaControlFlow_;
|
||||
};
|
||||
}
|
||||
|
||||
void spv::inReadableOrder(Block* root, std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||
{
|
||||
ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
//
|
||||
// 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 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.
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
namespace spv {
|
||||
|
||||
void SpvBuildLogger::tbdFunctionality(const std::string& f)
|
||||
{
|
||||
if (std::find(std::begin(tbdFeatures), std::end(tbdFeatures), f) == std::end(tbdFeatures))
|
||||
tbdFeatures.push_back(f);
|
||||
}
|
||||
|
||||
void SpvBuildLogger::missingFunctionality(const std::string& f)
|
||||
{
|
||||
if (std::find(std::begin(missingFeatures), std::end(missingFeatures), f) == std::end(missingFeatures))
|
||||
missingFeatures.push_back(f);
|
||||
}
|
||||
|
||||
std::string SpvBuildLogger::getAllMessages() const {
|
||||
std::ostringstream messages;
|
||||
for (auto it = tbdFeatures.cbegin(); it != tbdFeatures.cend(); ++it)
|
||||
messages << "TBD functionality: " << *it << "\n";
|
||||
for (auto it = missingFeatures.cbegin(); it != missingFeatures.cend(); ++it)
|
||||
messages << "Missing functionality: " << *it << "\n";
|
||||
for (auto it = warnings.cbegin(); it != warnings.cend(); ++it)
|
||||
messages << "warning: " << *it << "\n";
|
||||
for (auto it = errors.cbegin(); it != errors.cend(); ++it)
|
||||
messages << "error: " << *it << "\n";
|
||||
return messages.str();
|
||||
}
|
||||
|
||||
} // end spv namespace
|
||||
|
||||
#endif
|
|
@ -1,83 +0,0 @@
|
|||
//
|
||||
// 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 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.
|
||||
|
||||
#ifndef GLSLANG_SPIRV_LOGGER_H
|
||||
#define GLSLANG_SPIRV_LOGGER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace spv {
|
||||
|
||||
// A class for holding all SPIR-V build status messages, including
|
||||
// missing/TBD functionalities, warnings, and errors.
|
||||
class SpvBuildLogger {
|
||||
public:
|
||||
SpvBuildLogger() {}
|
||||
|
||||
#ifdef GLSLANG_WEB
|
||||
void tbdFunctionality(const std::string& f) { }
|
||||
void missingFunctionality(const std::string& f) { }
|
||||
void warning(const std::string& w) { }
|
||||
void error(const std::string& e) { errors.push_back(e); }
|
||||
std::string getAllMessages() { return ""; }
|
||||
#else
|
||||
|
||||
// Registers a TBD functionality.
|
||||
void tbdFunctionality(const std::string& f);
|
||||
// Registers a missing functionality.
|
||||
void missingFunctionality(const std::string& f);
|
||||
|
||||
// Logs a warning.
|
||||
void warning(const std::string& w) { warnings.push_back(w); }
|
||||
// Logs an error.
|
||||
void error(const std::string& e) { errors.push_back(e); }
|
||||
|
||||
// Returns all messages accumulated in the order of:
|
||||
// TBD functionalities, missing functionalities, warnings, errors.
|
||||
std::string getAllMessages() const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
SpvBuildLogger(const SpvBuildLogger&);
|
||||
|
||||
std::vector<std::string> tbdFeatures;
|
||||
std::vector<std::string> missingFeatures;
|
||||
std::vector<std::string> warnings;
|
||||
std::vector<std::string> errors;
|
||||
};
|
||||
|
||||
} // end spv namespace
|
||||
|
||||
#endif // GLSLANG_SPIRV_LOGGER_H
|
|
@ -1,50 +0,0 @@
|
|||
// Copyright (c) 2020 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 SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||
#define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
NonSemanticDebugPrintfRevision = 1,
|
||||
NonSemanticDebugPrintfRevision_BitWidthPadding = 0x7fffffff
|
||||
};
|
||||
|
||||
enum NonSemanticDebugPrintfInstructions {
|
||||
NonSemanticDebugPrintfDebugPrintf = 1,
|
||||
NonSemanticDebugPrintfInstructionsMax = 0x7fffffff
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -1,304 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2015 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 SPIRVREMAPPER_H
|
||||
#define SPIRVREMAPPER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
|
||||
namespace spv {
|
||||
|
||||
// MSVC defines __cplusplus as an older value, even when it supports almost all of 11.
|
||||
// We handle that here by making our own symbol.
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700)
|
||||
# define use_cpp11 1
|
||||
#endif
|
||||
|
||||
class spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
enum Options {
|
||||
NONE = 0,
|
||||
STRIP = (1<<0),
|
||||
MAP_TYPES = (1<<1),
|
||||
MAP_NAMES = (1<<2),
|
||||
MAP_FUNCS = (1<<3),
|
||||
DCE_FUNCS = (1<<4),
|
||||
DCE_VARS = (1<<5),
|
||||
DCE_TYPES = (1<<6),
|
||||
OPT_LOADSTORE = (1<<7),
|
||||
OPT_FWD_LS = (1<<8), // EXPERIMENTAL: PRODUCES INVALID SCHEMA-0 SPIRV
|
||||
MAP_ALL = (MAP_TYPES | MAP_NAMES | MAP_FUNCS),
|
||||
DCE_ALL = (DCE_FUNCS | DCE_VARS | DCE_TYPES),
|
||||
OPT_ALL = (OPT_LOADSTORE),
|
||||
|
||||
ALL_BUT_STRIP = (MAP_ALL | DCE_ALL | OPT_ALL),
|
||||
DO_EVERYTHING = (STRIP | ALL_BUT_STRIP)
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace SPV
|
||||
|
||||
#if !defined (use_cpp11)
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
|
||||
namespace spv {
|
||||
class spirvbin_t : public spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
spirvbin_t(int /*verbose = 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");
|
||||
exit(5);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace SPV
|
||||
|
||||
#else // defined (use_cpp11)
|
||||
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <cassert>
|
||||
|
||||
#include "spirv.hpp"
|
||||
#include "spvIR.h"
|
||||
|
||||
namespace spv {
|
||||
|
||||
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
|
||||
class spirvbin_t : public spirvbin_base_t
|
||||
{
|
||||
public:
|
||||
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose), errorLatch(false)
|
||||
{ }
|
||||
|
||||
virtual ~spirvbin_t() { }
|
||||
|
||||
// remap on an existing binary in memory
|
||||
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// Type for error/log handler functions
|
||||
typedef std::function<void(const std::string&)> errorfn_t;
|
||||
typedef std::function<void(const std::string&)> logfn_t;
|
||||
|
||||
// Register error/log handling functions (can be lambda fn / functor / etc)
|
||||
static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
|
||||
static void registerLogHandler(logfn_t handler) { logHandler = handler; }
|
||||
|
||||
protected:
|
||||
// This can be overridden to provide other message behavior if needed
|
||||
virtual void msg(int minVerbosity, int indent, const std::string& txt) const;
|
||||
|
||||
private:
|
||||
// Local to global, or global to local ID map
|
||||
typedef std::unordered_map<spv::Id, spv::Id> idmap_t;
|
||||
typedef std::unordered_set<spv::Id> idset_t;
|
||||
typedef std::unordered_map<spv::Id, int> blockmap_t;
|
||||
|
||||
void remap(std::uint32_t opts = DO_EVERYTHING);
|
||||
|
||||
// Map of names to IDs
|
||||
typedef std::unordered_map<std::string, spv::Id> namemap_t;
|
||||
|
||||
typedef std::uint32_t spirword_t;
|
||||
|
||||
typedef std::pair<unsigned, unsigned> range_t;
|
||||
typedef std::function<void(spv::Id&)> idfn_t;
|
||||
typedef std::function<bool(spv::Op, unsigned start)> instfn_t;
|
||||
|
||||
// Special Values for ID map:
|
||||
static const spv::Id unmapped; // unchanged from default value
|
||||
static const spv::Id unused; // unused ID
|
||||
static const int header_size; // SPIR header = 5 words
|
||||
|
||||
class id_iterator_t;
|
||||
|
||||
// For mapping type entries between different shaders
|
||||
typedef std::vector<spirword_t> typeentry_t;
|
||||
typedef std::map<spv::Id, typeentry_t> globaltypes_t;
|
||||
|
||||
// A set that preserves position order, and a reverse map
|
||||
typedef std::set<int> posmap_t;
|
||||
typedef std::unordered_map<spv::Id, int> posmap_rev_t;
|
||||
|
||||
// Maps and ID to the size of its base type, if known.
|
||||
typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;
|
||||
|
||||
// handle error
|
||||
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;
|
||||
|
||||
spv::Id& asId(unsigned word) { return spv[word]; }
|
||||
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
||||
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
|
||||
std::uint32_t asOpCodeHash(unsigned word);
|
||||
spv::Decoration asDecoration(unsigned word) const { return spv::Decoration(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)); }
|
||||
unsigned idPos(spv::Id id) const;
|
||||
|
||||
static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
|
||||
static spv::Op opOpCode(spirword_t data) { return spv::Op(data & spv::OpCodeMask); }
|
||||
|
||||
// Header access & set methods
|
||||
spirword_t magic() const { return spv[0]; } // return magic number
|
||||
spirword_t bound() const { return spv[3]; } // return Id bound from header
|
||||
spirword_t bound(spirword_t b) { return spv[3] = b; }
|
||||
spirword_t genmagic() const { return spv[2]; } // generator magic
|
||||
spirword_t genmagic(spirword_t m) { return spv[2] = m; }
|
||||
spirword_t schemaNum() const { return spv[4]; } // schema number from header
|
||||
|
||||
// Mapping fns: get
|
||||
spv::Id localId(spv::Id id) const { return idMapL[id]; }
|
||||
|
||||
// Mapping fns: set
|
||||
inline spv::Id localId(spv::Id id, spv::Id newId);
|
||||
void countIds(spv::Id id);
|
||||
|
||||
// Return next unused new local ID.
|
||||
// NOTE: boost::dynamic_bitset would be more efficient due to find_next(),
|
||||
// which std::vector<bool> doens't have.
|
||||
inline spv::Id nextUnusedId(spv::Id id);
|
||||
|
||||
void buildLocalMaps();
|
||||
std::string literalString(unsigned word) const; // Return literal as a std::string
|
||||
int literalStringWords(const std::string& str) const { return (int(str.size())+4)/4; }
|
||||
|
||||
bool isNewIdMapped(spv::Id newId) const { return isMapped(newId); }
|
||||
bool isOldIdUnmapped(spv::Id oldId) const { return localId(oldId) == unmapped; }
|
||||
bool isOldIdUnused(spv::Id oldId) const { return localId(oldId) == unused; }
|
||||
bool isOldIdMapped(spv::Id oldId) const { return !isOldIdUnused(oldId) && !isOldIdUnmapped(oldId); }
|
||||
bool isFunction(spv::Id oldId) const { return fnPos.find(oldId) != fnPos.end(); }
|
||||
|
||||
// bool matchType(const globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const;
|
||||
// spv::Id findType(const globaltypes_t& globalTypes, spv::Id lt) const;
|
||||
std::uint32_t hashType(unsigned typeStart) const;
|
||||
|
||||
spirvbin_t& process(instfn_t, idfn_t, unsigned begin = 0, unsigned end = 0);
|
||||
int processInstruction(unsigned word, instfn_t, idfn_t);
|
||||
|
||||
void validate() const;
|
||||
void mapTypeConst();
|
||||
void mapFnBodies();
|
||||
void optLoadStore();
|
||||
void dceFuncs();
|
||||
void dceVars();
|
||||
void dceTypes();
|
||||
void mapNames();
|
||||
void foldIds(); // fold IDs to smallest space
|
||||
void forwardLoadStores(); // load store forwarding (EXPERIMENTAL)
|
||||
void offsetIds(); // create relative offset IDs
|
||||
|
||||
void applyMap(); // remap per local name map
|
||||
void mapRemainder(); // map any IDs we haven't touched yet
|
||||
void stripDebug(); // strip all debug info
|
||||
void stripDeadRefs(); // strips debug info for now-dead references after DCE
|
||||
void strip(); // remove debug symbols
|
||||
|
||||
std::vector<spirword_t> spv; // SPIR words
|
||||
|
||||
namemap_t nameMap; // ID names from OpName
|
||||
|
||||
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use
|
||||
// boost::dynamic_bitset, but we're trying to avoid a boost dependency.
|
||||
typedef std::uint64_t bits_t;
|
||||
std::vector<bits_t> mapped; // which new IDs have been mapped
|
||||
static const int mBits = sizeof(bits_t) * 4;
|
||||
|
||||
bool isMapped(spv::Id id) const { return id < maxMappedId() && ((mapped[id/mBits] & (1LL<<(id%mBits))) != 0); }
|
||||
void setMapped(spv::Id id) { resizeMapped(id); mapped[id/mBits] |= (1LL<<(id%mBits)); }
|
||||
void resizeMapped(spv::Id id) { if (id >= maxMappedId()) mapped.resize(id/mBits+1, 0); }
|
||||
size_t maxMappedId() const { return mapped.size() * mBits; }
|
||||
|
||||
// Add a strip range for a given instruction starting at 'start'
|
||||
// Note: avoiding brace initializers to please older versions os MSVC.
|
||||
void stripInst(unsigned start) { stripRange.push_back(range_t(start, start + asWordCount(start))); }
|
||||
|
||||
// Function start and end. use unordered_map because we'll have
|
||||
// many fewer functions than IDs.
|
||||
std::unordered_map<spv::Id, range_t> fnPos;
|
||||
|
||||
// Which functions are called, anywhere in the module, with a call count
|
||||
std::unordered_map<spv::Id, int> fnCalls;
|
||||
|
||||
posmap_t typeConstPos; // word positions that define types & consts (ordered)
|
||||
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
|
||||
|
||||
spv::Id entryPoint; // module entry point
|
||||
spv::Id largestNewId; // biggest new ID we have mapped anything to
|
||||
|
||||
// Sections of the binary to strip, given as [begin,end)
|
||||
std::vector<range_t> stripRange;
|
||||
|
||||
// processing options:
|
||||
std::uint32_t options;
|
||||
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 logfn_t logHandler;
|
||||
};
|
||||
|
||||
} // namespace SPV
|
||||
|
||||
#endif // defined (use_cpp11)
|
||||
#endif // SPIRVREMAPPER_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,838 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||
// Copyright (C) 2015-2020 Google, Inc.
|
||||
// Copyright (C) 2017 ARM Limited.
|
||||
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
//
|
||||
// "Builder" is an interface to fully build SPIR-V IR. Allocate one of
|
||||
// these to build (a thread safe) internal SPIR-V representation (IR),
|
||||
// and then dump it as a binary stream according to the SPIR-V specification.
|
||||
//
|
||||
// A Builder has a 1:1 relationship with a SPIR-V module.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef SpvBuilder_H
|
||||
#define SpvBuilder_H
|
||||
|
||||
#include "Logger.h"
|
||||
#include "spirv.hpp"
|
||||
#include "spvIR.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
namespace spv {
|
||||
|
||||
typedef enum {
|
||||
Spv_1_0 = (1 << 16),
|
||||
Spv_1_1 = (1 << 16) | (1 << 8),
|
||||
Spv_1_2 = (1 << 16) | (2 << 8),
|
||||
Spv_1_3 = (1 << 16) | (3 << 8),
|
||||
Spv_1_4 = (1 << 16) | (4 << 8),
|
||||
Spv_1_5 = (1 << 16) | (5 << 8),
|
||||
} SpvVersion;
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
||||
virtual ~Builder();
|
||||
|
||||
static const int maxMatrixSize = 4;
|
||||
|
||||
unsigned int getSpvVersion() const { return spvVersion; }
|
||||
|
||||
void setSource(spv::SourceLanguage lang, int version)
|
||||
{
|
||||
source = lang;
|
||||
sourceVersion = version;
|
||||
}
|
||||
spv::Id getStringId(const std::string& str)
|
||||
{
|
||||
auto sItr = stringIds.find(str);
|
||||
if (sItr != stringIds.end())
|
||||
return sItr->second;
|
||||
spv::Id strId = getUniqueId();
|
||||
Instruction* fileString = new Instruction(strId, NoType, OpString);
|
||||
const char* file_c_str = str.c_str();
|
||||
fileString->addStringOperand(file_c_str);
|
||||
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
||||
module.mapInstruction(fileString);
|
||||
stringIds[file_c_str] = strId;
|
||||
return strId;
|
||||
}
|
||||
void setSourceFile(const std::string& file)
|
||||
{
|
||||
sourceFileStringId = getStringId(file);
|
||||
}
|
||||
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); }
|
||||
void removeExtension(const char* ext)
|
||||
{
|
||||
extensions.erase(ext);
|
||||
}
|
||||
void addIncorporatedExtension(const char* ext, SpvVersion incorporatedVersion)
|
||||
{
|
||||
if (getSpvVersion() < static_cast<unsigned>(incorporatedVersion))
|
||||
addExtension(ext);
|
||||
}
|
||||
void promoteIncorporatedExtension(const char* baseExt, const char* promoExt, SpvVersion incorporatedVersion)
|
||||
{
|
||||
removeExtension(baseExt);
|
||||
addIncorporatedExtension(promoExt, incorporatedVersion);
|
||||
}
|
||||
void addInclude(const std::string& name, const std::string& text)
|
||||
{
|
||||
spv::Id incId = getStringId(name);
|
||||
includeFiles[incId] = &text;
|
||||
}
|
||||
Id import(const char*);
|
||||
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
||||
{
|
||||
addressModel = addr;
|
||||
memoryModel = mem;
|
||||
}
|
||||
|
||||
void addCapability(spv::Capability cap) { capabilities.insert(cap); }
|
||||
|
||||
// To get a new <id> for anything needing a new one.
|
||||
Id getUniqueId() { return ++uniqueId; }
|
||||
|
||||
// To get a set of new <id>s, e.g., for a set of function parameters
|
||||
Id getUniqueIds(int numIds)
|
||||
{
|
||||
Id id = uniqueId + 1;
|
||||
uniqueId += numIds;
|
||||
return id;
|
||||
}
|
||||
|
||||
// Generate OpLine for non-filename-based #line directives (ie no filename
|
||||
// seen yet): Log the current line, and if different than the last one,
|
||||
// issue a new OpLine using the new line and current source file name.
|
||||
void setLine(int line);
|
||||
|
||||
// If filename null, generate OpLine for non-filename-based line directives,
|
||||
// else do filename-based: Log the current line and file, and if different
|
||||
// than the last one, issue a new OpLine using the new line and file
|
||||
// name.
|
||||
void setLine(int line, const char* filename);
|
||||
// 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).
|
||||
Id makeVoidType();
|
||||
Id makeBoolType();
|
||||
Id makePointer(StorageClass, Id pointee);
|
||||
Id makeForwardPointer(StorageClass);
|
||||
Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
|
||||
Id makeIntegerType(int width, bool hasSign); // generic
|
||||
Id makeIntType(int width) { return makeIntegerType(width, true); }
|
||||
Id makeUintType(int width) { return makeIntegerType(width, false); }
|
||||
Id makeFloatType(int width);
|
||||
Id makeStructType(const std::vector<Id>& members, const char*);
|
||||
Id makeStructResultType(Id type0, Id type1);
|
||||
Id makeVectorType(Id component, int size);
|
||||
Id makeMatrixType(Id component, int cols, int rows);
|
||||
Id makeArrayType(Id element, Id sizeId, int stride); // 0 stride means no stride decoration
|
||||
Id makeRuntimeArray(Id element);
|
||||
Id makeFunctionType(Id returnType, const std::vector<Id>& paramTypes);
|
||||
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
|
||||
Id makeSamplerType();
|
||||
Id makeSampledImageType(Id imageType);
|
||||
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
||||
|
||||
// accelerationStructureNV type
|
||||
Id makeAccelerationStructureType();
|
||||
// rayQueryEXT type
|
||||
Id makeRayQueryType();
|
||||
|
||||
// For querying about types.
|
||||
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
||||
Id getDerefTypeId(Id resultId) const;
|
||||
Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
|
||||
Op getTypeClass(Id typeId) const { return getOpCode(typeId); }
|
||||
Op getMostBasicTypeClass(Id typeId) const;
|
||||
int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
|
||||
int getNumTypeConstituents(Id typeId) const;
|
||||
int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }
|
||||
Id getScalarTypeId(Id typeId) const;
|
||||
Id getContainedTypeId(Id typeId) const;
|
||||
Id getContainedTypeId(Id typeId, int) const;
|
||||
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
|
||||
ImageFormat getImageTypeFormat(Id typeId) const
|
||||
{ return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
|
||||
|
||||
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
|
||||
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
||||
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
|
||||
bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); }
|
||||
bool isCooperativeMatrix(Id resultId)const { return isCooperativeMatrixType(getTypeId(resultId)); }
|
||||
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
||||
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
|
||||
|
||||
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 isScalarType(Id typeId) const
|
||||
{ return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt ||
|
||||
getTypeClass(typeId) == OpTypeBool; }
|
||||
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
|
||||
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
|
||||
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
|
||||
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
|
||||
#ifdef GLSLANG_WEB
|
||||
bool isCooperativeMatrixType(Id typeId)const { return false; }
|
||||
#else
|
||||
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
|
||||
#endif
|
||||
bool isAggregateType(Id typeId) const
|
||||
{ return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
|
||||
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
|
||||
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
||||
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
||||
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
|
||||
bool containsPhysicalStorageBufferOrArray(Id typeId) const;
|
||||
|
||||
bool isConstantOpCode(Op opcode) const;
|
||||
bool isSpecConstantOpCode(Op opcode) const;
|
||||
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
|
||||
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
|
||||
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
|
||||
unsigned int getConstantScalar(Id resultId) const
|
||||
{ return module.getInstruction(resultId)->getImmediateOperand(0); }
|
||||
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
|
||||
{
|
||||
assert(isMatrixType(typeId));
|
||||
return getNumTypeConstituents(typeId);
|
||||
}
|
||||
int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
|
||||
int getTypeNumRows(Id typeId) const
|
||||
{
|
||||
assert(isMatrixType(typeId));
|
||||
return getNumTypeComponents(getContainedTypeId(typeId));
|
||||
}
|
||||
int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
|
||||
|
||||
Dim getTypeDimensionality(Id typeId) const
|
||||
{
|
||||
assert(isImageType(typeId));
|
||||
return (Dim)module.getInstruction(typeId)->getImmediateOperand(1);
|
||||
}
|
||||
Id getImageType(Id resultId) const
|
||||
{
|
||||
Id typeId = getTypeId(resultId);
|
||||
assert(isImageType(typeId) || isSampledImageType(typeId));
|
||||
return isSampledImageType(typeId) ? module.getInstruction(typeId)->getIdOperand(0) : typeId;
|
||||
}
|
||||
bool isArrayedImageType(Id typeId) const
|
||||
{
|
||||
assert(isImageType(typeId));
|
||||
return module.getInstruction(typeId)->getImmediateOperand(3) != 0;
|
||||
}
|
||||
|
||||
// For making new constants (will return old constant if the requested one was already made).
|
||||
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 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 makeUint64Constant(unsigned long long u, bool specConstant = false)
|
||||
{ return makeInt64Constant(makeUintType(64), u, specConstant); }
|
||||
Id makeFloatConstant(float f, 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.
|
||||
Id makeCompositeConstant(Id type, const std::vector<Id>& comps, bool specConst = false);
|
||||
|
||||
// Methods for adding information outside the CFG.
|
||||
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
|
||||
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
||||
void addName(Id, const char* name);
|
||||
void addMemberName(Id, int member, const char* name);
|
||||
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, const char*);
|
||||
|
||||
// At the end of what block do the next create*() instructions go?
|
||||
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
||||
Block* getBuildPoint() const { return buildPoint; }
|
||||
|
||||
// Make the entry-point function. The returned pointer is only valid
|
||||
// for the lifetime of this builder.
|
||||
Function* makeEntryPoint(const char*);
|
||||
|
||||
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||
// Return the function, pass back the entry.
|
||||
// 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, const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
|
||||
|
||||
// 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.
|
||||
void makeReturn(bool implicit, Id retVal = 0);
|
||||
|
||||
// Generate all the code needed to finish up a function.
|
||||
void leaveFunction();
|
||||
|
||||
// Create a discard.
|
||||
void makeDiscard();
|
||||
|
||||
// Create a global or function local or IO variable.
|
||||
Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult);
|
||||
|
||||
// Create an intermediate with an undefined value.
|
||||
Id createUndefined(Id type);
|
||||
|
||||
// Store into an Id and return the l-value
|
||||
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
|
||||
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||
|
||||
// Load from an Id and return it
|
||||
Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
|
||||
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||
|
||||
// Create an OpAccessChain instruction
|
||||
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
||||
|
||||
// Create an OpArrayLength instruction
|
||||
Id createArrayLength(Id base, unsigned int member);
|
||||
|
||||
// Create an OpCooperativeMatrixLengthNV instruction
|
||||
Id createCooperativeMatrixLength(Id type);
|
||||
|
||||
// Create an OpCompositeExtract instruction
|
||||
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
|
||||
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, const std::vector<unsigned>& indexes);
|
||||
|
||||
Id createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex);
|
||||
Id createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex);
|
||||
|
||||
void createNoResultOp(Op);
|
||||
void createNoResultOp(Op, Id operand);
|
||||
void createNoResultOp(Op, const std::vector<Id>& operands);
|
||||
void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
|
||||
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
|
||||
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
|
||||
Id createUnaryOp(Op, Id typeId, Id operand);
|
||||
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
|
||||
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<IdImmediate>& operands);
|
||||
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);
|
||||
|
||||
// Take an rvalue (source) and a set of channels to extract from it to
|
||||
// make a new rvalue, which is returned.
|
||||
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
|
||||
// source components into the lvalue where the 'channels' say to put them.
|
||||
// An updated version of the target is returned.
|
||||
// (No true lvalue or stores are used.)
|
||||
Id createLvalueSwizzle(Id typeId, Id target, Id source, const std::vector<unsigned>& channels);
|
||||
|
||||
// If both the id and precision are valid, the id
|
||||
// gets tagged with the requested precision.
|
||||
// The passed in id is always the returned id, to simplify use patterns.
|
||||
Id setPrecision(Id id, Decoration precision)
|
||||
{
|
||||
if (precision != NoPrecision && id != NoResult)
|
||||
addDecoration(id, precision);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
// Can smear a scalar to a vector for the following forms:
|
||||
// - promoteScalar(scalar, vector) // smear scalar to width of vector
|
||||
// - promoteScalar(vector, scalar) // smear scalar to width of vector
|
||||
// - promoteScalar(pointer, scalar) // smear scalar to width of what pointer points to
|
||||
// - promoteScalar(scalar, scalar) // do nothing
|
||||
// Other forms are not allowed.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Note: One of the arguments will change, with the result coming back that way rather than
|
||||
// through the return value.
|
||||
void promoteScalar(Decoration precision, Id& left, Id& right);
|
||||
|
||||
// Make a value by smearing the scalar to fill the type.
|
||||
// vectorType should be the correct type for making a vector of scalarVal.
|
||||
// (No conversions are done.)
|
||||
Id smearScalar(Decoration precision, Id scalarVal, Id vectorType);
|
||||
|
||||
// Create a call to a built-in function.
|
||||
Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, const std::vector<Id>& args);
|
||||
|
||||
// List of parameters used to create a texture operation
|
||||
struct TextureParameters {
|
||||
Id sampler;
|
||||
Id coords;
|
||||
Id bias;
|
||||
Id lod;
|
||||
Id Dref;
|
||||
Id offset;
|
||||
Id offsets;
|
||||
Id gradX;
|
||||
Id gradY;
|
||||
Id sample;
|
||||
Id component;
|
||||
Id texelOut;
|
||||
Id lodClamp;
|
||||
Id granularity;
|
||||
Id coarse;
|
||||
bool nonprivate;
|
||||
bool volatil;
|
||||
};
|
||||
|
||||
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
||||
Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
|
||||
bool noImplicit, const TextureParameters&, ImageOperandsMask);
|
||||
|
||||
// Emit the OpTextureQuery* instruction that was passed in.
|
||||
// Figure out the right return value and type, and return it.
|
||||
Id createTextureQueryCall(Op, const TextureParameters&, bool isUnsignedResult);
|
||||
|
||||
Id createSamplePositionCall(Decoration precision, Id, Id);
|
||||
|
||||
Id createBitFieldExtractCall(Decoration precision, Id, Id, Id, bool isSigned);
|
||||
Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id);
|
||||
|
||||
// Reduction comparison for composites: For equal and not-equal resulting in a scalar.
|
||||
Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);
|
||||
|
||||
// OpCompositeConstruct
|
||||
Id createCompositeConstruct(Id typeId, const std::vector<Id>& constituents);
|
||||
|
||||
// vector or scalar constructor
|
||||
Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId);
|
||||
|
||||
// matrix constructor
|
||||
Id createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id constructee);
|
||||
|
||||
// Helper to use for building nested control flow with if-then-else.
|
||||
class If {
|
||||
public:
|
||||
If(Id condition, unsigned int ctrl, Builder& builder);
|
||||
~If() {}
|
||||
|
||||
void makeBeginElse();
|
||||
void makeEndIf();
|
||||
|
||||
private:
|
||||
If(const If&);
|
||||
If& operator=(If&);
|
||||
|
||||
Builder& builder;
|
||||
Id condition;
|
||||
unsigned int control;
|
||||
Function* function;
|
||||
Block* headerBlock;
|
||||
Block* thenBlock;
|
||||
Block* elseBlock;
|
||||
Block* mergeBlock;
|
||||
};
|
||||
|
||||
// Make a switch statement. A switch has 'numSegments' of pieces of code, not containing
|
||||
// any case/default labels, all separated by one or more case/default labels. Each possible
|
||||
// case value v is a jump to the caseValues[v] segment. The defaultSegment is also in this
|
||||
// number space. How to compute the value is given by 'condition', as in switch(condition).
|
||||
//
|
||||
// The SPIR-V Builder will maintain the stack of post-switch merge blocks for nested switches.
|
||||
//
|
||||
// Use a defaultSegment < 0 if there is no default segment (to branch to post switch).
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
||||
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
|
||||
|
||||
// Add a branch to the innermost switch's merge block.
|
||||
void addSwitchBreak();
|
||||
|
||||
// Move to the next code segment, passing in the return argument in makeSwitch()
|
||||
void nextSwitchSegment(std::vector<Block*>& segmentBB, int segment);
|
||||
|
||||
// Finish off the innermost switch.
|
||||
void endSwitch(std::vector<Block*>& segmentBB);
|
||||
|
||||
struct LoopBlocks {
|
||||
LoopBlocks(Block& head, Block& body, Block& merge, Block& continue_target) :
|
||||
head(head), body(body), merge(merge), continue_target(continue_target) { }
|
||||
Block &head, &body, &merge, &continue_target;
|
||||
private:
|
||||
LoopBlocks();
|
||||
LoopBlocks& operator=(const LoopBlocks&) = delete;
|
||||
};
|
||||
|
||||
// Start a new loop and prepare the builder to generate code for it. Until
|
||||
// closeLoop() is called for this loop, createLoopContinue() and
|
||||
// createLoopExit() will target its corresponding blocks.
|
||||
LoopBlocks& makeNewLoop();
|
||||
|
||||
// Create a new block in the function containing the build point. Memory is
|
||||
// owned by the function object.
|
||||
Block& makeNewBlock();
|
||||
|
||||
// Add a branch to the continue_target of the current (innermost) loop.
|
||||
void createLoopContinue();
|
||||
|
||||
// Add an exit (e.g. "break") from the innermost loop that we're currently
|
||||
// in.
|
||||
void createLoopExit();
|
||||
|
||||
// Close the innermost loop that you're in
|
||||
void closeLoop();
|
||||
|
||||
//
|
||||
// Access chain design for an R-Value vs. L-Value:
|
||||
//
|
||||
// There is a single access chain the builder is building at
|
||||
// any particular time. Such a chain can be used to either to a load or
|
||||
// a store, when desired.
|
||||
//
|
||||
// Expressions can be r-values, l-values, or both, or only r-values:
|
||||
// a[b.c].d = .... // l-value
|
||||
// ... = a[b.c].d; // r-value, that also looks like an l-value
|
||||
// ++a[b.c].d; // r-value and l-value
|
||||
// (x + y)[2]; // r-value only, can't possibly be l-value
|
||||
//
|
||||
// Computing an r-value means generating code. Hence,
|
||||
// r-values should only be computed when they are needed, not speculatively.
|
||||
//
|
||||
// Computing an l-value means saving away information for later use in the compiler,
|
||||
// no code is generated until the l-value is later dereferenced. It is okay
|
||||
// to speculatively generate an l-value, just not okay to speculatively dereference it.
|
||||
//
|
||||
// The base of the access chain (the left-most variable or expression
|
||||
// from which everything is based) can be set either as an l-value
|
||||
// or as an r-value. Most efficient would be to set an l-value if one
|
||||
// is available. If an expression was evaluated, the resulting r-value
|
||||
// can be set as the chain base.
|
||||
//
|
||||
// The users of this single access chain can save and restore if they
|
||||
// want to nest or manage multiple chains.
|
||||
//
|
||||
|
||||
struct AccessChain {
|
||||
Id base; // for l-values, pointer to the base object, for r-values, the base object
|
||||
std::vector<Id> indexChain;
|
||||
Id instr; // cache the instruction that generates this access chain
|
||||
std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
|
||||
Id component; // a dynamic component index, can coexist with a swizzle,
|
||||
// done after the swizzle, NoResult if not present
|
||||
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied;
|
||||
// NoType unless a swizzle or component is present
|
||||
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
||||
unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment.
|
||||
// Only tracks base and (optional) component selection alignment.
|
||||
|
||||
// Accumulate whether anything in the chain of structures has coherent decorations.
|
||||
struct CoherentFlags {
|
||||
CoherentFlags() { clear(); }
|
||||
#ifdef GLSLANG_WEB
|
||||
void clear() { }
|
||||
bool isVolatile() const { return false; }
|
||||
CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
|
||||
#else
|
||||
bool isVolatile() const { return volatil; }
|
||||
bool anyCoherent() const {
|
||||
return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent ||
|
||||
subgroupcoherent || shadercallcoherent;
|
||||
}
|
||||
|
||||
unsigned coherent : 1;
|
||||
unsigned devicecoherent : 1;
|
||||
unsigned queuefamilycoherent : 1;
|
||||
unsigned workgroupcoherent : 1;
|
||||
unsigned subgroupcoherent : 1;
|
||||
unsigned shadercallcoherent : 1;
|
||||
unsigned nonprivate : 1;
|
||||
unsigned volatil : 1;
|
||||
unsigned isImage : 1;
|
||||
|
||||
void clear() {
|
||||
coherent = 0;
|
||||
devicecoherent = 0;
|
||||
queuefamilycoherent = 0;
|
||||
workgroupcoherent = 0;
|
||||
subgroupcoherent = 0;
|
||||
shadercallcoherent = 0;
|
||||
nonprivate = 0;
|
||||
volatil = 0;
|
||||
isImage = 0;
|
||||
}
|
||||
|
||||
CoherentFlags operator |=(const CoherentFlags &other) {
|
||||
coherent |= other.coherent;
|
||||
devicecoherent |= other.devicecoherent;
|
||||
queuefamilycoherent |= other.queuefamilycoherent;
|
||||
workgroupcoherent |= other.workgroupcoherent;
|
||||
subgroupcoherent |= other.subgroupcoherent;
|
||||
shadercallcoherent |= other.shadercallcoherent;
|
||||
nonprivate |= other.nonprivate;
|
||||
volatil |= other.volatil;
|
||||
isImage |= other.isImage;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
CoherentFlags coherentFlags;
|
||||
};
|
||||
|
||||
//
|
||||
// the SPIR-V builder maintains a single active chain that
|
||||
// the following methods operate on
|
||||
//
|
||||
|
||||
// for external save and restore
|
||||
AccessChain getAccessChain() { return accessChain; }
|
||||
void setAccessChain(AccessChain newChain) { accessChain = newChain; }
|
||||
|
||||
// clear accessChain
|
||||
void clearAccessChain();
|
||||
|
||||
// set new base as an l-value base
|
||||
void setAccessChainLValue(Id lValue)
|
||||
{
|
||||
assert(isPointer(lValue));
|
||||
accessChain.base = lValue;
|
||||
}
|
||||
|
||||
// set new base value as an r-value
|
||||
void setAccessChainRValue(Id rValue)
|
||||
{
|
||||
accessChain.isRValue = true;
|
||||
accessChain.base = rValue;
|
||||
}
|
||||
|
||||
// push offset onto the end of the chain
|
||||
void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||
{
|
||||
accessChain.indexChain.push_back(offset);
|
||||
accessChain.coherentFlags |= coherentFlags;
|
||||
accessChain.alignment |= alignment;
|
||||
}
|
||||
|
||||
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
|
||||
AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
|
||||
|
||||
// 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, AccessChain::CoherentFlags coherentFlags,
|
||||
unsigned int alignment)
|
||||
{
|
||||
if (accessChain.swizzle.size() != 1) {
|
||||
accessChain.component = component;
|
||||
if (accessChain.preSwizzleBaseType == NoType)
|
||||
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
||||
}
|
||||
accessChain.coherentFlags |= coherentFlags;
|
||||
accessChain.alignment |= alignment;
|
||||
}
|
||||
|
||||
// use accessChain and swizzle to store value
|
||||
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
|
||||
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||
|
||||
// use accessChain and swizzle to load an r-value
|
||||
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType,
|
||||
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
|
||||
unsigned int alignment = 0);
|
||||
|
||||
// Return whether or not the access chain can be represented in SPIR-V
|
||||
// as an l-value.
|
||||
// E.g., a[3].yx cannot be, while a[3].y and a[3].y[x] can be.
|
||||
bool isSpvLvalue() const { return accessChain.swizzle.size() <= 1; }
|
||||
|
||||
// get the direct pointer for an l-value
|
||||
Id accessChainGetLValue();
|
||||
|
||||
// Get the inferred SPIR-V type of the result of the current access chain,
|
||||
// based on the type of the base and the chain of dereferences.
|
||||
Id accessChainGetInferredType();
|
||||
|
||||
// Add capabilities, extensions, remove unneeded decorations, etc.,
|
||||
// based on the resulting SPIR-V.
|
||||
void postProcess();
|
||||
|
||||
// Prune unreachable blocks in the CFG and remove unneeded decorations.
|
||||
void postProcessCFG();
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// Add capabilities, extensions based on instructions in the module.
|
||||
void postProcessFeatures();
|
||||
// Hook to visit each instruction in a block in a function
|
||||
void postProcess(Instruction&);
|
||||
// Hook to visit each non-32-bit sized float/int operation in a block.
|
||||
void postProcessType(const Instruction&, spv::Id typeId);
|
||||
#endif
|
||||
|
||||
void dump(std::vector<unsigned int>&) const;
|
||||
|
||||
void createBranch(Block* block);
|
||||
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
||||
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
|
||||
const std::vector<unsigned int>& operands);
|
||||
|
||||
// Sets to generate opcode for specialization constants.
|
||||
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
||||
// Sets to generate opcode for non-specialization constants (normal mode).
|
||||
void setToNormalCodeGenMode() { generatingOpCodeForSpecConst = false; }
|
||||
// Check if the builder is generating code for spec constants.
|
||||
bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; }
|
||||
|
||||
protected:
|
||||
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
|
||||
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
|
||||
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value);
|
||||
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
|
||||
Id findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps);
|
||||
Id findStructConstant(Id typeId, const std::vector<Id>& comps);
|
||||
Id collapseAccessChain();
|
||||
void remapDynamicSwizzle();
|
||||
void transferAccessChainSwizzle(bool dynamic);
|
||||
void simplifyAccessChainSwizzle();
|
||||
void createAndSetNoPredecessorBlock(const char*);
|
||||
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
||||
void dumpSourceInstructions(std::vector<unsigned int>&) const;
|
||||
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
|
||||
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
||||
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
|
||||
const;
|
||||
|
||||
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||
SourceLanguage source;
|
||||
int sourceVersion;
|
||||
spv::Id sourceFileStringId;
|
||||
std::string sourceText;
|
||||
int currentLine;
|
||||
const char* currentFile;
|
||||
bool emitOpLines;
|
||||
std::set<std::string> extensions;
|
||||
std::vector<const char*> sourceExtensions;
|
||||
std::vector<const char*> moduleProcesses;
|
||||
AddressingModel addressModel;
|
||||
MemoryModel memoryModel;
|
||||
std::set<spv::Capability> capabilities;
|
||||
int builderNumber;
|
||||
Module module;
|
||||
Block* buildPoint;
|
||||
Id uniqueId;
|
||||
Function* entryPointFunction;
|
||||
bool generatingOpCodeForSpecConst;
|
||||
AccessChain accessChain;
|
||||
|
||||
// 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> > entryPoints;
|
||||
std::vector<std::unique_ptr<Instruction> > executionModes;
|
||||
std::vector<std::unique_ptr<Instruction> > names;
|
||||
std::vector<std::unique_ptr<Instruction> > decorations;
|
||||
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
|
||||
std::vector<std::unique_ptr<Instruction> > externals;
|
||||
std::vector<std::unique_ptr<Function> > functions;
|
||||
|
||||
// not output, internally used for quick & dirty canonical (unique) creation
|
||||
|
||||
// map type opcodes to constant inst.
|
||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
|
||||
// map struct-id to constant instructions
|
||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
|
||||
// map type opcodes to type instructions
|
||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
|
||||
|
||||
// stack of switches
|
||||
std::stack<Block*> switchMerges;
|
||||
|
||||
// Our loop stack.
|
||||
std::stack<LoopBlocks> loops;
|
||||
|
||||
// map from strings to their string ids
|
||||
std::unordered_map<std::string, spv::Id> stringIds;
|
||||
|
||||
// map from include file name ids to their contents
|
||||
std::map<spv::Id, const std::string*> includeFiles;
|
||||
|
||||
// The stream for outputting warnings and errors.
|
||||
SpvBuildLogger* logger;
|
||||
}; // end Builder class
|
||||
|
||||
}; // end spv namespace
|
||||
|
||||
#endif // SpvBuilder_H
|
|
@ -1,450 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
|
||||
//
|
||||
// Post-processing for SPIR-V IR, in internal form, not standard binary form.
|
||||
//
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
|
||||
#include "SpvBuilder.h"
|
||||
|
||||
#include "spirv.hpp"
|
||||
#include "GlslangToSpv.h"
|
||||
#include "SpvBuilder.h"
|
||||
namespace spv {
|
||||
#include "GLSL.std.450.h"
|
||||
#include "GLSL.ext.KHR.h"
|
||||
#include "GLSL.ext.EXT.h"
|
||||
#include "GLSL.ext.AMD.h"
|
||||
#include "GLSL.ext.NV.h"
|
||||
}
|
||||
|
||||
namespace spv {
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// Hook to visit each operand type and result type of an instruction.
|
||||
// Will be called multiple times for one instruction, once for each typed
|
||||
// operand and the result.
|
||||
void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||
{
|
||||
// Characterize the type being questioned
|
||||
Id basicTypeOp = getMostBasicTypeClass(typeId);
|
||||
int width = 0;
|
||||
if (basicTypeOp == OpTypeFloat || basicTypeOp == OpTypeInt)
|
||||
width = getScalarTypeWidth(typeId);
|
||||
|
||||
// Do opcode-specific checks
|
||||
switch (inst.getOpCode()) {
|
||||
case OpLoad:
|
||||
case OpStore:
|
||||
if (basicTypeOp == OpTypeStruct) {
|
||||
if (containsType(typeId, OpTypeInt, 8))
|
||||
addCapability(CapabilityInt8);
|
||||
if (containsType(typeId, OpTypeInt, 16))
|
||||
addCapability(CapabilityInt16);
|
||||
if (containsType(typeId, OpTypeFloat, 16))
|
||||
addCapability(CapabilityFloat16);
|
||||
} else {
|
||||
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
|
||||
if (width == 8) {
|
||||
switch (storageClass) {
|
||||
case StorageClassPhysicalStorageBufferEXT:
|
||||
case StorageClassUniform:
|
||||
case StorageClassStorageBuffer:
|
||||
case StorageClassPushConstant:
|
||||
break;
|
||||
default:
|
||||
addCapability(CapabilityInt8);
|
||||
break;
|
||||
}
|
||||
} else if (width == 16) {
|
||||
switch (storageClass) {
|
||||
case StorageClassPhysicalStorageBufferEXT:
|
||||
case StorageClassUniform:
|
||||
case StorageClassStorageBuffer:
|
||||
case StorageClassPushConstant:
|
||||
case StorageClassInput:
|
||||
case StorageClassOutput:
|
||||
break;
|
||||
default:
|
||||
if (basicTypeOp == OpTypeInt)
|
||||
addCapability(CapabilityInt16);
|
||||
if (basicTypeOp == OpTypeFloat)
|
||||
addCapability(CapabilityFloat16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OpAccessChain:
|
||||
case OpPtrAccessChain:
|
||||
case OpCopyObject:
|
||||
break;
|
||||
case OpFConvert:
|
||||
case OpSConvert:
|
||||
case OpUConvert:
|
||||
// Look for any 8/16-bit storage capabilities. If there are none, assume that
|
||||
// the convert instruction requires the Float16/Int8/16 capability.
|
||||
if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) {
|
||||
bool foundStorage = false;
|
||||
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
|
||||
spv::Capability cap = *it;
|
||||
if (cap == spv::CapabilityStorageInputOutput16 ||
|
||||
cap == spv::CapabilityStoragePushConstant16 ||
|
||||
cap == spv::CapabilityStorageUniformBufferBlock16 ||
|
||||
cap == spv::CapabilityStorageUniform16) {
|
||||
foundStorage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundStorage) {
|
||||
if (containsType(typeId, OpTypeFloat, 16))
|
||||
addCapability(CapabilityFloat16);
|
||||
if (containsType(typeId, OpTypeInt, 16))
|
||||
addCapability(CapabilityInt16);
|
||||
}
|
||||
}
|
||||
if (containsType(typeId, OpTypeInt, 8)) {
|
||||
bool foundStorage = false;
|
||||
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
|
||||
spv::Capability cap = *it;
|
||||
if (cap == spv::CapabilityStoragePushConstant8 ||
|
||||
cap == spv::CapabilityUniformAndStorageBuffer8BitAccess ||
|
||||
cap == spv::CapabilityStorageBuffer8BitAccess) {
|
||||
foundStorage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundStorage) {
|
||||
addCapability(CapabilityInt8);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OpExtInst:
|
||||
switch (inst.getImmediateOperand(1)) {
|
||||
case GLSLstd450Frexp:
|
||||
case GLSLstd450FrexpStruct:
|
||||
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeInt, 16))
|
||||
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
|
||||
break;
|
||||
case GLSLstd450InterpolateAtCentroid:
|
||||
case GLSLstd450InterpolateAtSample:
|
||||
case GLSLstd450InterpolateAtOffset:
|
||||
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeFloat, 16))
|
||||
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (basicTypeOp == OpTypeFloat && width == 16)
|
||||
addCapability(CapabilityFloat16);
|
||||
if (basicTypeOp == OpTypeInt && width == 16)
|
||||
addCapability(CapabilityInt16);
|
||||
if (basicTypeOp == OpTypeInt && width == 8)
|
||||
addCapability(CapabilityInt8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Called for each instruction that resides in a block.
|
||||
void Builder::postProcess(Instruction& inst)
|
||||
{
|
||||
// Add capabilities based simply on the opcode.
|
||||
switch (inst.getOpCode()) {
|
||||
case OpExtInst:
|
||||
switch (inst.getImmediateOperand(1)) {
|
||||
case GLSLstd450InterpolateAtCentroid:
|
||||
case GLSLstd450InterpolateAtSample:
|
||||
case GLSLstd450InterpolateAtOffset:
|
||||
addCapability(CapabilityInterpolationFunction);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case OpDPdxFine:
|
||||
case OpDPdyFine:
|
||||
case OpFwidthFine:
|
||||
case OpDPdxCoarse:
|
||||
case OpDPdyCoarse:
|
||||
case OpFwidthCoarse:
|
||||
addCapability(CapabilityDerivativeControl);
|
||||
break;
|
||||
|
||||
case OpImageQueryLod:
|
||||
case OpImageQuerySize:
|
||||
case OpImageQuerySizeLod:
|
||||
case OpImageQuerySamples:
|
||||
case OpImageQueryLevels:
|
||||
addCapability(CapabilityImageQuery);
|
||||
break;
|
||||
|
||||
case OpGroupNonUniformPartitionNV:
|
||||
addExtension(E_SPV_NV_shader_subgroup_partitioned);
|
||||
addCapability(CapabilityGroupNonUniformPartitionedNV);
|
||||
break;
|
||||
|
||||
case OpLoad:
|
||||
case OpStore:
|
||||
{
|
||||
// For any load/store to a PhysicalStorageBufferEXT, walk the accesschain
|
||||
// index list to compute the misalignment. The pre-existing alignment value
|
||||
// (set via Builder::AccessChain::alignment) only accounts for the base of
|
||||
// the reference type and any scalar component selection in the accesschain,
|
||||
// and this function computes the rest from the SPIR-V Offset decorations.
|
||||
Instruction *accessChain = module.getInstruction(inst.getIdOperand(0));
|
||||
if (accessChain->getOpCode() == OpAccessChain) {
|
||||
Instruction *base = module.getInstruction(accessChain->getIdOperand(0));
|
||||
// Get the type of the base of the access chain. It must be a pointer type.
|
||||
Id typeId = base->getTypeId();
|
||||
Instruction *type = module.getInstruction(typeId);
|
||||
assert(type->getOpCode() == OpTypePointer);
|
||||
if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) {
|
||||
break;
|
||||
}
|
||||
// Get the pointee type.
|
||||
typeId = type->getIdOperand(1);
|
||||
type = module.getInstruction(typeId);
|
||||
// Walk the index list for the access chain. For each index, find any
|
||||
// misalignment that can apply when accessing the member/element via
|
||||
// Offset/ArrayStride/MatrixStride decorations, and bitwise OR them all
|
||||
// together.
|
||||
int alignment = 0;
|
||||
for (int i = 1; i < accessChain->getNumOperands(); ++i) {
|
||||
Instruction *idx = module.getInstruction(accessChain->getIdOperand(i));
|
||||
if (type->getOpCode() == OpTypeStruct) {
|
||||
assert(idx->getOpCode() == OpConstant);
|
||||
unsigned int c = idx->getImmediateOperand(0);
|
||||
|
||||
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||
if (decoration.get()->getOpCode() == OpMemberDecorate &&
|
||||
decoration.get()->getIdOperand(0) == typeId &&
|
||||
decoration.get()->getImmediateOperand(1) == c &&
|
||||
(decoration.get()->getImmediateOperand(2) == DecorationOffset ||
|
||||
decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) {
|
||||
alignment |= decoration.get()->getImmediateOperand(3);
|
||||
}
|
||||
};
|
||||
std::for_each(decorations.begin(), decorations.end(), function);
|
||||
// get the next member type
|
||||
typeId = type->getIdOperand(c);
|
||||
type = module.getInstruction(typeId);
|
||||
} else if (type->getOpCode() == OpTypeArray ||
|
||||
type->getOpCode() == OpTypeRuntimeArray) {
|
||||
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||
if (decoration.get()->getOpCode() == OpDecorate &&
|
||||
decoration.get()->getIdOperand(0) == typeId &&
|
||||
decoration.get()->getImmediateOperand(1) == DecorationArrayStride) {
|
||||
alignment |= decoration.get()->getImmediateOperand(2);
|
||||
}
|
||||
};
|
||||
std::for_each(decorations.begin(), decorations.end(), function);
|
||||
// Get the element type
|
||||
typeId = type->getIdOperand(0);
|
||||
type = module.getInstruction(typeId);
|
||||
} else {
|
||||
// Once we get to any non-aggregate type, we're done.
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(inst.getNumOperands() >= 3);
|
||||
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
|
||||
assert(memoryAccess & MemoryAccessAlignedMask);
|
||||
static_cast<void>(memoryAccess);
|
||||
// Compute the index of the alignment operand.
|
||||
int alignmentIdx = 2;
|
||||
if (inst.getOpCode() == OpStore)
|
||||
alignmentIdx++;
|
||||
// Merge new and old (mis)alignment
|
||||
alignment |= inst.getImmediateOperand(alignmentIdx);
|
||||
// Pick the LSB
|
||||
alignment = alignment & ~(alignment & (alignment-1));
|
||||
// update the Aligned operand
|
||||
inst.setImmediateOperand(alignmentIdx, alignment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Checks based on type
|
||||
if (inst.getTypeId() != NoType)
|
||||
postProcessType(inst, inst.getTypeId());
|
||||
for (int op = 0; op < inst.getNumOperands(); ++op) {
|
||||
if (inst.isIdOperand(op)) {
|
||||
// In blocks, these are always result ids, but we are relying on
|
||||
// getTypeId() to return NoType for things like OpLabel.
|
||||
if (getTypeId(inst.getIdOperand(op)) != NoType)
|
||||
postProcessType(inst, getTypeId(inst.getIdOperand(op)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// comment in header
|
||||
void Builder::postProcessCFG()
|
||||
{
|
||||
// reachableBlocks is the set of blockss reached via control flow, or which are
|
||||
// unreachable continue targert or unreachable merge.
|
||||
std::unordered_set<const Block*> reachableBlocks;
|
||||
std::unordered_map<Block*, Block*> headerForUnreachableContinue;
|
||||
std::unordered_set<Block*> unreachableMerges;
|
||||
std::unordered_set<Id> unreachableDefinitions;
|
||||
// Collect IDs defined in unreachable blocks. For each function, label the
|
||||
// reachable blocks first. Then for each unreachable block, collect the
|
||||
// result IDs of the instructions in it.
|
||||
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||
Function* f = *fi;
|
||||
Block* entry = f->getEntryBlock();
|
||||
inReadableOrder(entry,
|
||||
[&reachableBlocks, &unreachableMerges, &headerForUnreachableContinue]
|
||||
(Block* b, ReachReason why, Block* header) {
|
||||
reachableBlocks.insert(b);
|
||||
if (why == ReachDeadContinue) headerForUnreachableContinue[b] = header;
|
||||
if (why == ReachDeadMerge) unreachableMerges.insert(b);
|
||||
});
|
||||
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||
Block* b = *bi;
|
||||
if (unreachableMerges.count(b) != 0 || headerForUnreachableContinue.count(b) != 0) {
|
||||
auto ii = b->getInstructions().cbegin();
|
||||
++ii; // Keep potential decorations on the label.
|
||||
for (; ii != b->getInstructions().cend(); ++ii)
|
||||
unreachableDefinitions.insert(ii->get()->getResultId());
|
||||
} else if (reachableBlocks.count(b) == 0) {
|
||||
// The normal case for unreachable code. All definitions are considered dead.
|
||||
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ++ii)
|
||||
unreachableDefinitions.insert(ii->get()->getResultId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modify unreachable merge blocks and unreachable continue targets.
|
||||
// Delete their contents.
|
||||
for (auto mergeIter = unreachableMerges.begin(); mergeIter != unreachableMerges.end(); ++mergeIter) {
|
||||
(*mergeIter)->rewriteAsCanonicalUnreachableMerge();
|
||||
}
|
||||
for (auto continueIter = headerForUnreachableContinue.begin();
|
||||
continueIter != headerForUnreachableContinue.end();
|
||||
++continueIter) {
|
||||
Block* continue_target = continueIter->first;
|
||||
Block* header = continueIter->second;
|
||||
continue_target->rewriteAsCanonicalUnreachableContinue(header);
|
||||
}
|
||||
|
||||
// Remove unneeded decorations, for unreachable instructions
|
||||
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
||||
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
|
||||
Id decoration_id = I.get()->getIdOperand(0);
|
||||
return unreachableDefinitions.count(decoration_id) != 0;
|
||||
}),
|
||||
decorations.end());
|
||||
}
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
// comment in header
|
||||
void Builder::postProcessFeatures() {
|
||||
// Add per-instruction capabilities, extensions, etc.,
|
||||
|
||||
// Look for any 8/16 bit type in physical storage buffer class, and set the
|
||||
// appropriate capability. This happens in createSpvVariable for other storage
|
||||
// classes, but there isn't always a variable for physical storage buffer.
|
||||
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
||||
Instruction* type = groupedTypes[OpTypePointer][t];
|
||||
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
|
||||
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
|
||||
addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
|
||||
addCapability(spv::CapabilityStorageBuffer8BitAccess);
|
||||
}
|
||||
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
|
||||
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
|
||||
addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
|
||||
addCapability(spv::CapabilityStorageBuffer16BitAccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process all block-contained instructions
|
||||
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||
Function* f = *fi;
|
||||
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||
Block* b = *bi;
|
||||
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
||||
postProcess(*ii->get());
|
||||
|
||||
// For all local variables that contain pointers to PhysicalStorageBufferEXT, check whether
|
||||
// there is an existing restrict/aliased decoration. If we don't find one, add Aliased as the
|
||||
// default.
|
||||
for (auto vi = b->getLocalVariables().cbegin(); vi != b->getLocalVariables().cend(); vi++) {
|
||||
const Instruction& inst = *vi->get();
|
||||
Id resultId = inst.getResultId();
|
||||
if (containsPhysicalStorageBufferOrArray(getDerefTypeId(resultId))) {
|
||||
bool foundDecoration = false;
|
||||
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||
if (decoration.get()->getIdOperand(0) == resultId &&
|
||||
decoration.get()->getOpCode() == OpDecorate &&
|
||||
(decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT ||
|
||||
decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) {
|
||||
foundDecoration = true;
|
||||
}
|
||||
};
|
||||
std::for_each(decorations.begin(), decorations.end(), function);
|
||||
if (!foundDecoration) {
|
||||
addDecoration(resultId, spv::DecorationAliasedPointerEXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// comment in header
|
||||
void Builder::postProcess() {
|
||||
postProcessCFG();
|
||||
#ifndef GLSLANG_WEB
|
||||
postProcessFeatures();
|
||||
#endif
|
||||
}
|
||||
|
||||
}; // end spv namespace
|
|
@ -1,217 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||
// Copyright (C) 2018-2020 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.
|
||||
|
||||
//
|
||||
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||
//
|
||||
|
||||
#if ENABLE_OPT
|
||||
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
#include "SpvTools.h"
|
||||
#include "spirv-tools/optimizer.hpp"
|
||||
#include "spirv-tools/libspirv.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
||||
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger)
|
||||
{
|
||||
switch (spvVersion.vulkan) {
|
||||
case glslang::EShTargetVulkan_1_0:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_0;
|
||||
case glslang::EShTargetVulkan_1_1:
|
||||
switch (spvVersion.spv) {
|
||||
case EShTargetSpv_1_0:
|
||||
case EShTargetSpv_1_1:
|
||||
case EShTargetSpv_1_2:
|
||||
case EShTargetSpv_1_3:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||
case EShTargetSpv_1_4:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_1_SPIRV_1_4;
|
||||
default:
|
||||
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||
}
|
||||
case glslang::EShTargetVulkan_1_2:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (spvVersion.openGl > 0)
|
||||
return spv_target_env::SPV_ENV_OPENGL_4_5;
|
||||
|
||||
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
||||
}
|
||||
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
||||
{
|
||||
// disassemble
|
||||
spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
|
||||
spv_text text;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spvBinaryToText(context, spirv.data(), spirv.size(),
|
||||
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
|
||||
&text, &diagnostic);
|
||||
|
||||
// dump
|
||||
if (diagnostic == nullptr)
|
||||
out << text->str;
|
||||
else
|
||||
spvDiagnosticPrint(diagnostic);
|
||||
|
||||
// teardown
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, bool prelegalization)
|
||||
{
|
||||
// validate
|
||||
spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||
spv_const_binary_t binary = { spirv.data(), spirv.size() };
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
spv_validator_options options = spvValidatorOptionsCreate();
|
||||
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
|
||||
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
|
||||
spvValidateWithOptions(context, options, &binary, &diagnostic);
|
||||
|
||||
// report
|
||||
if (diagnostic != nullptr) {
|
||||
logger->error("SPIRV-Tools Validation Errors");
|
||||
logger->error(diagnostic->error);
|
||||
}
|
||||
|
||||
// tear down
|
||||
spvValidatorOptionsDestroy(options);
|
||||
spvDiagnosticDestroy(diagnostic);
|
||||
spvContextDestroy(context);
|
||||
}
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
||||
// legalizing HLSL SPIR-V.
|
||||
void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger* logger, const SpvOptions* options)
|
||||
{
|
||||
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
|
||||
|
||||
spvtools::Optimizer optimizer(target_env);
|
||||
optimizer.SetMessageConsumer(
|
||||
[](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) {
|
||||
auto &out = std::cerr;
|
||||
switch (level)
|
||||
{
|
||||
case SPV_MSG_FATAL:
|
||||
case SPV_MSG_INTERNAL_ERROR:
|
||||
case SPV_MSG_ERROR:
|
||||
out << "error: ";
|
||||
break;
|
||||
case SPV_MSG_WARNING:
|
||||
out << "warning: ";
|
||||
break;
|
||||
case SPV_MSG_INFO:
|
||||
case SPV_MSG_DEBUG:
|
||||
out << "info: ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (source)
|
||||
{
|
||||
out << source << ":";
|
||||
}
|
||||
out << position.line << ":" << position.column << ":" << position.index << ":";
|
||||
if (message)
|
||||
{
|
||||
out << " " << message;
|
||||
}
|
||||
out << std::endl;
|
||||
});
|
||||
|
||||
// If debug (specifically source line info) is being generated, propagate
|
||||
// line information into all SPIR-V instructions. This avoids loss of
|
||||
// information when instructions are deleted or moved. Later, remove
|
||||
// redundant information to minimize final SPRIR-V size.
|
||||
if (options->generateDebugInfo) {
|
||||
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
|
||||
}
|
||||
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
||||
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
|
||||
optimizer.RegisterPass(spvtools::CreateEliminateDeadFunctionsPass());
|
||||
optimizer.RegisterPass(spvtools::CreateScalarReplacementPass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalAccessChainConvertPass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalSingleBlockLoadStoreElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalSingleStoreElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateBlockMergePass());
|
||||
optimizer.RegisterPass(spvtools::CreateLocalMultiStoreElimPass());
|
||||
optimizer.RegisterPass(spvtools::CreateIfConversionPass());
|
||||
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||
if (options->optimizeSize) {
|
||||
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
|
||||
}
|
||||
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
||||
if (options->generateDebugInfo) {
|
||||
optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass());
|
||||
}
|
||||
|
||||
spvtools::OptimizerOptions spvOptOptions;
|
||||
optimizer.SetTargetEnv(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||
spvOptOptions.set_run_validator(false); // The validator may run as a separate step later on
|
||||
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||
}
|
||||
|
||||
}; // end namespace glslang
|
||||
|
||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014-2016 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.
|
||||
|
||||
//
|
||||
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef GLSLANG_SPV_TOOLS_H
|
||||
#define GLSLANG_SPV_TOOLS_H
|
||||
|
||||
#ifdef ENABLE_OPT
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
#include "glslang/MachineIndependent/localintermediate.h"
|
||||
#include "Logger.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
struct SpvOptions {
|
||||
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
||||
optimizeSize(false), disassemble(false), validate(false) { }
|
||||
bool generateDebugInfo;
|
||||
bool disableOptimizer;
|
||||
bool optimizeSize;
|
||||
bool disassemble;
|
||||
bool validate;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_OPT
|
||||
|
||||
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
||||
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
|
||||
|
||||
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*, bool prelegalization);
|
||||
|
||||
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
||||
// legalizing HLSL SPIR-V.
|
||||
void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||
spv::SpvBuildLogger*, const SpvOptions*);
|
||||
|
||||
#endif
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // GLSLANG_SPV_TOOLS_H
|
|
@ -1,81 +0,0 @@
|
|||
// 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(static_cast<void*>(&dest), &source, sizeof(dest));
|
||||
return dest;
|
||||
}
|
||||
|
||||
// SetBits<T, First, Num> returns an integer of type <T> with bits set
|
||||
// for position <First> through <First + Num - 1>, counting from the least
|
||||
// significant bit. In particular when Num == 0, no positions are set to 1.
|
||||
// A static assert will be triggered if First + Num > sizeof(T) * 8, that is,
|
||||
// a bit that will not fit in the underlying type is set.
|
||||
template <typename T, size_t First = 0, size_t Num = 0>
|
||||
struct SetBits {
|
||||
static_assert(First < sizeof(T) * 8,
|
||||
"Tried to set a bit that is shifted too far.");
|
||||
const static T get = (T(1) << First) | SetBits<T, First + 1, Num - 1>::get;
|
||||
};
|
||||
|
||||
template <typename T, size_t Last>
|
||||
struct SetBits<T, Last, 0> {
|
||||
const static T get = T(0);
|
||||
};
|
||||
|
||||
// This is all compile-time so we can put our tests right here.
|
||||
static_assert(SetBits<uint32_t, 0, 0>::get == uint32_t(0x00000000),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 0, 1>::get == uint32_t(0x00000001),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 31, 1>::get == uint32_t(0x80000000),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 1, 2>::get == uint32_t(0x00000006),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 30, 2>::get == uint32_t(0xc0000000),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 0, 31>::get == uint32_t(0x7FFFFFFF),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 0, 32>::get == uint32_t(0xFFFFFFFF),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint32_t, 16, 16>::get == uint32_t(0xFFFF0000),
|
||||
"SetBits failed");
|
||||
|
||||
static_assert(SetBits<uint64_t, 0, 1>::get == uint64_t(0x0000000000000001LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 63, 1>::get == uint64_t(0x8000000000000000LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 62, 2>::get == uint64_t(0xc000000000000000LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 31, 1>::get == uint64_t(0x0000000080000000LL),
|
||||
"SetBits failed");
|
||||
static_assert(SetBits<uint64_t, 16, 16>::get == uint64_t(0x00000000FFFF0000LL),
|
||||
"SetBits failed");
|
||||
|
||||
} // namespace spvutils
|
||||
|
||||
#endif // LIBSPIRV_UTIL_BITUTILS_H_
|
|
@ -1,743 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014-2015 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.
|
||||
|
||||
//
|
||||
// Disassembler for SPIR-V.
|
||||
//
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#include <stack>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
#include "disassemble.h"
|
||||
#include "doc.h"
|
||||
#include "SpvTools.h"
|
||||
|
||||
namespace spv {
|
||||
extern "C" {
|
||||
// Include C-based headers that don't have a namespace
|
||||
#include "GLSL.std.450.h"
|
||||
#include "GLSL.ext.AMD.h"
|
||||
#include "GLSL.ext.NV.h"
|
||||
}
|
||||
}
|
||||
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
||||
|
||||
namespace spv {
|
||||
|
||||
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
|
||||
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
|
||||
|
||||
static void Kill(std::ostream& out, const char* message)
|
||||
{
|
||||
out << std::endl << "Disassembly failed: " << message << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// used to identify the extended instruction library imported when printing
|
||||
enum ExtInstSet {
|
||||
GLSL450Inst,
|
||||
GLSLextAMDInst,
|
||||
GLSLextNVInst,
|
||||
OpenCLExtInst,
|
||||
NonSemanticDebugPrintfExtInst,
|
||||
};
|
||||
|
||||
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
|
||||
class SpirvStream {
|
||||
public:
|
||||
SpirvStream(std::ostream& out, const std::vector<unsigned int>& stream) : out(out), stream(stream), word(0), nextNestedControl(0) { }
|
||||
virtual ~SpirvStream() { }
|
||||
|
||||
void validate();
|
||||
void processInstructions();
|
||||
|
||||
protected:
|
||||
SpirvStream(const SpirvStream&);
|
||||
SpirvStream& operator=(const SpirvStream&);
|
||||
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : OpNop; }
|
||||
|
||||
// Output methods
|
||||
void outputIndent();
|
||||
void formatId(Id id, std::stringstream&);
|
||||
void outputResultId(Id id);
|
||||
void outputTypeId(Id id);
|
||||
void outputId(Id id);
|
||||
void outputMask(OperandClass operandClass, unsigned mask);
|
||||
void disassembleImmediates(int numOperands);
|
||||
void disassembleIds(int numOperands);
|
||||
int disassembleString();
|
||||
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
|
||||
|
||||
// Data
|
||||
std::ostream& out; // where to write the disassembly
|
||||
const std::vector<unsigned int>& stream; // the actual word stream
|
||||
int size; // the size of the word stream
|
||||
int word; // the next word of the stream to read
|
||||
|
||||
// map each <id> to the instruction that created it
|
||||
Id bound;
|
||||
std::vector<unsigned int> idInstruction; // the word offset into the stream where the instruction for result [id] starts; 0 if not yet seen (forward reference or function parameter)
|
||||
|
||||
std::vector<std::string> idDescriptor; // the best text string known for explaining the <id>
|
||||
|
||||
// schema
|
||||
unsigned int schema;
|
||||
|
||||
// stack of structured-merge points
|
||||
std::stack<Id> nestedControl;
|
||||
Id nextNestedControl; // need a slight delay for when we are nested
|
||||
};
|
||||
|
||||
void SpirvStream::validate()
|
||||
{
|
||||
size = (int)stream.size();
|
||||
if (size < 4)
|
||||
Kill(out, "stream is too short");
|
||||
|
||||
// Magic number
|
||||
if (stream[word++] != MagicNumber) {
|
||||
out << "Bad magic number";
|
||||
return;
|
||||
}
|
||||
|
||||
// Version
|
||||
out << "// Module Version " << std::hex << stream[word++] << std::endl;
|
||||
|
||||
// Generator's magic number
|
||||
out << "// Generated by (magic number): " << std::hex << stream[word++] << std::dec << std::endl;
|
||||
|
||||
// Result <id> bound
|
||||
bound = stream[word++];
|
||||
idInstruction.resize(bound);
|
||||
idDescriptor.resize(bound);
|
||||
out << "// Id's are bound by " << bound << std::endl;
|
||||
out << std::endl;
|
||||
|
||||
// Reserved schema, must be 0 for now
|
||||
schema = stream[word++];
|
||||
if (schema != 0)
|
||||
Kill(out, "bad schema, must be 0");
|
||||
}
|
||||
|
||||
// Loop over all the instructions, in order, processing each.
|
||||
// Boiler plate for each is handled here directly, the rest is dispatched.
|
||||
void SpirvStream::processInstructions()
|
||||
{
|
||||
// Instructions
|
||||
while (word < size) {
|
||||
int instructionStart = word;
|
||||
|
||||
// Instruction wordCount and opcode
|
||||
unsigned int firstWord = stream[word];
|
||||
unsigned wordCount = firstWord >> WordCountShift;
|
||||
Op opCode = (Op)(firstWord & OpCodeMask);
|
||||
int nextInst = word + wordCount;
|
||||
++word;
|
||||
|
||||
// Presence of full instruction
|
||||
if (nextInst > size)
|
||||
Kill(out, "stream instruction terminated too early");
|
||||
|
||||
// Base for computing number of operands; will be updated as more is learned
|
||||
unsigned numOperands = wordCount - 1;
|
||||
|
||||
// Type <id>
|
||||
Id typeId = 0;
|
||||
if (InstructionDesc[opCode].hasType()) {
|
||||
typeId = stream[word++];
|
||||
--numOperands;
|
||||
}
|
||||
|
||||
// Result <id>
|
||||
Id resultId = 0;
|
||||
if (InstructionDesc[opCode].hasResult()) {
|
||||
resultId = stream[word++];
|
||||
--numOperands;
|
||||
|
||||
// save instruction for future reference
|
||||
idInstruction[resultId] = instructionStart;
|
||||
}
|
||||
|
||||
outputResultId(resultId);
|
||||
outputTypeId(typeId);
|
||||
outputIndent();
|
||||
|
||||
// Hand off the Op and all its operands
|
||||
disassembleInstruction(resultId, typeId, opCode, numOperands);
|
||||
if (word != nextInst) {
|
||||
out << " ERROR, incorrect number of operands consumed. At " << word << " instead of " << nextInst << " instruction start was " << instructionStart;
|
||||
word = nextInst;
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::outputIndent()
|
||||
{
|
||||
for (int i = 0; i < (int)nestedControl.size(); ++i)
|
||||
out << " ";
|
||||
}
|
||||
|
||||
void SpirvStream::formatId(Id id, std::stringstream& idStream)
|
||||
{
|
||||
if (id != 0) {
|
||||
// On instructions with no IDs, this is called with "0", which does not
|
||||
// have to be within ID bounds on null shaders.
|
||||
if (id >= bound)
|
||||
Kill(out, "Bad <id>");
|
||||
|
||||
idStream << id;
|
||||
if (idDescriptor[id].size() > 0)
|
||||
idStream << "(" << idDescriptor[id] << ")";
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::outputResultId(Id id)
|
||||
{
|
||||
const int width = 16;
|
||||
std::stringstream idStream;
|
||||
formatId(id, idStream);
|
||||
out << std::setw(width) << std::right << idStream.str();
|
||||
if (id != 0)
|
||||
out << ":";
|
||||
else
|
||||
out << " ";
|
||||
|
||||
if (nestedControl.size() && id == nestedControl.top())
|
||||
nestedControl.pop();
|
||||
}
|
||||
|
||||
void SpirvStream::outputTypeId(Id id)
|
||||
{
|
||||
const int width = 12;
|
||||
std::stringstream idStream;
|
||||
formatId(id, idStream);
|
||||
out << std::setw(width) << std::right << idStream.str() << " ";
|
||||
}
|
||||
|
||||
void SpirvStream::outputId(Id id)
|
||||
{
|
||||
if (id >= bound)
|
||||
Kill(out, "Bad <id>");
|
||||
|
||||
out << id;
|
||||
if (idDescriptor[id].size() > 0)
|
||||
out << "(" << idDescriptor[id] << ")";
|
||||
}
|
||||
|
||||
void SpirvStream::outputMask(OperandClass operandClass, unsigned mask)
|
||||
{
|
||||
if (mask == 0)
|
||||
out << "None";
|
||||
else {
|
||||
for (int m = 0; m < OperandClassParams[operandClass].ceiling; ++m) {
|
||||
if (mask & (1 << m))
|
||||
out << OperandClassParams[operandClass].getName(m) << " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::disassembleImmediates(int numOperands)
|
||||
{
|
||||
for (int i = 0; i < numOperands; ++i) {
|
||||
out << stream[word++];
|
||||
if (i < numOperands - 1)
|
||||
out << " ";
|
||||
}
|
||||
}
|
||||
|
||||
void SpirvStream::disassembleIds(int numOperands)
|
||||
{
|
||||
for (int i = 0; i < numOperands; ++i) {
|
||||
outputId(stream[word++]);
|
||||
if (i < numOperands - 1)
|
||||
out << " ";
|
||||
}
|
||||
}
|
||||
|
||||
// return the number of operands consumed by the string
|
||||
int SpirvStream::disassembleString()
|
||||
{
|
||||
int startWord = word;
|
||||
|
||||
out << " \"";
|
||||
|
||||
const char* wordString;
|
||||
bool done = false;
|
||||
do {
|
||||
unsigned int content = stream[word];
|
||||
wordString = (const char*)&content;
|
||||
for (int charCount = 0; charCount < 4; ++charCount) {
|
||||
if (*wordString == 0) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
out << *(wordString++);
|
||||
}
|
||||
++word;
|
||||
} while (! done);
|
||||
|
||||
out << "\"";
|
||||
|
||||
return word - startWord;
|
||||
}
|
||||
|
||||
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
|
||||
{
|
||||
// Process the opcode
|
||||
|
||||
out << (OpcodeString(opCode) + 2); // leave out the "Op"
|
||||
|
||||
if (opCode == OpLoopMerge || opCode == OpSelectionMerge)
|
||||
nextNestedControl = stream[word];
|
||||
else if (opCode == OpBranchConditional || opCode == OpSwitch) {
|
||||
if (nextNestedControl) {
|
||||
nestedControl.push(nextNestedControl);
|
||||
nextNestedControl = 0;
|
||||
}
|
||||
} else if (opCode == OpExtInstImport) {
|
||||
idDescriptor[resultId] = (const char*)(&stream[word]);
|
||||
}
|
||||
else {
|
||||
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
|
||||
switch (opCode) {
|
||||
case OpTypeInt:
|
||||
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;
|
||||
case OpTypeFloat:
|
||||
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;
|
||||
case OpTypeBool:
|
||||
idDescriptor[resultId] = "bool";
|
||||
break;
|
||||
case OpTypeStruct:
|
||||
idDescriptor[resultId] = "struct";
|
||||
break;
|
||||
case OpTypePointer:
|
||||
idDescriptor[resultId] = "ptr";
|
||||
break;
|
||||
case OpTypeVector:
|
||||
if (idDescriptor[stream[word]].size() > 0) {
|
||||
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");
|
||||
switch (stream[word + 1]) {
|
||||
case 2: idDescriptor[resultId].append("2"); break;
|
||||
case 3: idDescriptor[resultId].append("3"); break;
|
||||
case 4: idDescriptor[resultId].append("4"); break;
|
||||
case 8: idDescriptor[resultId].append("8"); break;
|
||||
case 16: idDescriptor[resultId].append("16"); break;
|
||||
case 32: idDescriptor[resultId].append("32"); break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the operands. Note, a new context-dependent set could be
|
||||
// swapped in mid-traversal.
|
||||
|
||||
// Handle images specially, so can put out helpful strings.
|
||||
if (opCode == OpTypeImage) {
|
||||
out << " ";
|
||||
disassembleIds(1);
|
||||
out << " " << DimensionString((Dim)stream[word++]);
|
||||
out << (stream[word++] != 0 ? " depth" : "");
|
||||
out << (stream[word++] != 0 ? " array" : "");
|
||||
out << (stream[word++] != 0 ? " multi-sampled" : "");
|
||||
switch (stream[word++]) {
|
||||
case 0: out << " runtime"; break;
|
||||
case 1: out << " sampled"; break;
|
||||
case 2: out << " nonsampled"; break;
|
||||
}
|
||||
out << " format:" << ImageFormatString((ImageFormat)stream[word++]);
|
||||
|
||||
if (numOperands == 8) {
|
||||
out << " " << AccessQualifierString(stream[word++]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle all the parameterized operands
|
||||
for (int op = 0; op < InstructionDesc[opCode].operands.getNum() && numOperands > 0; ++op) {
|
||||
out << " ";
|
||||
OperandClass operandClass = InstructionDesc[opCode].operands.getClass(op);
|
||||
switch (operandClass) {
|
||||
case OperandId:
|
||||
case OperandScope:
|
||||
case OperandMemorySemantics:
|
||||
disassembleIds(1);
|
||||
--numOperands;
|
||||
// Get names for printing "(XXX)" for readability, *after* this id
|
||||
if (opCode == OpName)
|
||||
idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
|
||||
break;
|
||||
case OperandVariableIds:
|
||||
disassembleIds(numOperands);
|
||||
return;
|
||||
case OperandImageOperands:
|
||||
outputMask(OperandImageOperands, stream[word++]);
|
||||
--numOperands;
|
||||
disassembleIds(numOperands);
|
||||
return;
|
||||
case OperandOptionalLiteral:
|
||||
case OperandVariableLiterals:
|
||||
if ((opCode == OpDecorate && stream[word - 1] == DecorationBuiltIn) ||
|
||||
(opCode == OpMemberDecorate && stream[word - 1] == DecorationBuiltIn)) {
|
||||
out << BuiltInString(stream[word++]);
|
||||
--numOperands;
|
||||
++op;
|
||||
}
|
||||
disassembleImmediates(numOperands);
|
||||
return;
|
||||
case OperandVariableIdLiteral:
|
||||
while (numOperands > 0) {
|
||||
out << std::endl;
|
||||
outputResultId(0);
|
||||
outputTypeId(0);
|
||||
outputIndent();
|
||||
out << " Type ";
|
||||
disassembleIds(1);
|
||||
out << ", member ";
|
||||
disassembleImmediates(1);
|
||||
numOperands -= 2;
|
||||
}
|
||||
return;
|
||||
case OperandVariableLiteralId:
|
||||
while (numOperands > 0) {
|
||||
out << std::endl;
|
||||
outputResultId(0);
|
||||
outputTypeId(0);
|
||||
outputIndent();
|
||||
out << " case ";
|
||||
disassembleImmediates(1);
|
||||
out << ": ";
|
||||
disassembleIds(1);
|
||||
numOperands -= 2;
|
||||
}
|
||||
return;
|
||||
case OperandLiteralNumber:
|
||||
disassembleImmediates(1);
|
||||
--numOperands;
|
||||
if (opCode == OpExtInst) {
|
||||
ExtInstSet extInstSet = GLSL450Inst;
|
||||
const char* name = idDescriptor[stream[word - 2]].c_str();
|
||||
if (strcmp("OpenCL.std", name) == 0) {
|
||||
extInstSet = OpenCLExtInst;
|
||||
} else if (strcmp("OpenCL.DebugInfo.100", name) == 0) {
|
||||
extInstSet = OpenCLExtInst;
|
||||
} else if (strcmp("NonSemantic.DebugPrintf", name) == 0) {
|
||||
extInstSet = NonSemanticDebugPrintfExtInst;
|
||||
} 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;
|
||||
} 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 ||
|
||||
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
|
||||
strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) {
|
||||
extInstSet = GLSLextNVInst;
|
||||
}
|
||||
unsigned entrypoint = stream[word - 1];
|
||||
if (extInstSet == GLSL450Inst) {
|
||||
if (entrypoint < GLSLstd450Count) {
|
||||
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
||||
}
|
||||
} else if (extInstSet == GLSLextAMDInst) {
|
||||
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
|
||||
}
|
||||
else if (extInstSet == GLSLextNVInst) {
|
||||
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
||||
} else if (extInstSet == NonSemanticDebugPrintfExtInst) {
|
||||
out << "(DebugPrintf)";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OperandOptionalLiteralString:
|
||||
case OperandLiteralString:
|
||||
numOperands -= disassembleString();
|
||||
break;
|
||||
case OperandMemoryAccess:
|
||||
outputMask(OperandMemoryAccess, stream[word++]);
|
||||
--numOperands;
|
||||
// Aligned is the only memory access operand that uses an immediate
|
||||
// value, and it is also the first operand that uses a value at all.
|
||||
if (stream[word-1] & MemoryAccessAlignedMask) {
|
||||
disassembleImmediates(1);
|
||||
numOperands--;
|
||||
if (numOperands)
|
||||
out << " ";
|
||||
}
|
||||
disassembleIds(numOperands);
|
||||
return;
|
||||
default:
|
||||
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
|
||||
|
||||
if (OperandClassParams[operandClass].bitmask)
|
||||
outputMask(operandClass, stream[word++]);
|
||||
else
|
||||
out << OperandClassParams[operandClass].getName(stream[word++]);
|
||||
--numOperands;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void GLSLstd450GetDebugNames(const char** names)
|
||||
{
|
||||
for (int i = 0; i < GLSLstd450Count; ++i)
|
||||
names[i] = "Unknown";
|
||||
|
||||
names[GLSLstd450Round] = "Round";
|
||||
names[GLSLstd450RoundEven] = "RoundEven";
|
||||
names[GLSLstd450Trunc] = "Trunc";
|
||||
names[GLSLstd450FAbs] = "FAbs";
|
||||
names[GLSLstd450SAbs] = "SAbs";
|
||||
names[GLSLstd450FSign] = "FSign";
|
||||
names[GLSLstd450SSign] = "SSign";
|
||||
names[GLSLstd450Floor] = "Floor";
|
||||
names[GLSLstd450Ceil] = "Ceil";
|
||||
names[GLSLstd450Fract] = "Fract";
|
||||
names[GLSLstd450Radians] = "Radians";
|
||||
names[GLSLstd450Degrees] = "Degrees";
|
||||
names[GLSLstd450Sin] = "Sin";
|
||||
names[GLSLstd450Cos] = "Cos";
|
||||
names[GLSLstd450Tan] = "Tan";
|
||||
names[GLSLstd450Asin] = "Asin";
|
||||
names[GLSLstd450Acos] = "Acos";
|
||||
names[GLSLstd450Atan] = "Atan";
|
||||
names[GLSLstd450Sinh] = "Sinh";
|
||||
names[GLSLstd450Cosh] = "Cosh";
|
||||
names[GLSLstd450Tanh] = "Tanh";
|
||||
names[GLSLstd450Asinh] = "Asinh";
|
||||
names[GLSLstd450Acosh] = "Acosh";
|
||||
names[GLSLstd450Atanh] = "Atanh";
|
||||
names[GLSLstd450Atan2] = "Atan2";
|
||||
names[GLSLstd450Pow] = "Pow";
|
||||
names[GLSLstd450Exp] = "Exp";
|
||||
names[GLSLstd450Log] = "Log";
|
||||
names[GLSLstd450Exp2] = "Exp2";
|
||||
names[GLSLstd450Log2] = "Log2";
|
||||
names[GLSLstd450Sqrt] = "Sqrt";
|
||||
names[GLSLstd450InverseSqrt] = "InverseSqrt";
|
||||
names[GLSLstd450Determinant] = "Determinant";
|
||||
names[GLSLstd450MatrixInverse] = "MatrixInverse";
|
||||
names[GLSLstd450Modf] = "Modf";
|
||||
names[GLSLstd450ModfStruct] = "ModfStruct";
|
||||
names[GLSLstd450FMin] = "FMin";
|
||||
names[GLSLstd450SMin] = "SMin";
|
||||
names[GLSLstd450UMin] = "UMin";
|
||||
names[GLSLstd450FMax] = "FMax";
|
||||
names[GLSLstd450SMax] = "SMax";
|
||||
names[GLSLstd450UMax] = "UMax";
|
||||
names[GLSLstd450FClamp] = "FClamp";
|
||||
names[GLSLstd450SClamp] = "SClamp";
|
||||
names[GLSLstd450UClamp] = "UClamp";
|
||||
names[GLSLstd450FMix] = "FMix";
|
||||
names[GLSLstd450Step] = "Step";
|
||||
names[GLSLstd450SmoothStep] = "SmoothStep";
|
||||
names[GLSLstd450Fma] = "Fma";
|
||||
names[GLSLstd450Frexp] = "Frexp";
|
||||
names[GLSLstd450FrexpStruct] = "FrexpStruct";
|
||||
names[GLSLstd450Ldexp] = "Ldexp";
|
||||
names[GLSLstd450PackSnorm4x8] = "PackSnorm4x8";
|
||||
names[GLSLstd450PackUnorm4x8] = "PackUnorm4x8";
|
||||
names[GLSLstd450PackSnorm2x16] = "PackSnorm2x16";
|
||||
names[GLSLstd450PackUnorm2x16] = "PackUnorm2x16";
|
||||
names[GLSLstd450PackHalf2x16] = "PackHalf2x16";
|
||||
names[GLSLstd450PackDouble2x32] = "PackDouble2x32";
|
||||
names[GLSLstd450UnpackSnorm2x16] = "UnpackSnorm2x16";
|
||||
names[GLSLstd450UnpackUnorm2x16] = "UnpackUnorm2x16";
|
||||
names[GLSLstd450UnpackHalf2x16] = "UnpackHalf2x16";
|
||||
names[GLSLstd450UnpackSnorm4x8] = "UnpackSnorm4x8";
|
||||
names[GLSLstd450UnpackUnorm4x8] = "UnpackUnorm4x8";
|
||||
names[GLSLstd450UnpackDouble2x32] = "UnpackDouble2x32";
|
||||
names[GLSLstd450Length] = "Length";
|
||||
names[GLSLstd450Distance] = "Distance";
|
||||
names[GLSLstd450Cross] = "Cross";
|
||||
names[GLSLstd450Normalize] = "Normalize";
|
||||
names[GLSLstd450FaceForward] = "FaceForward";
|
||||
names[GLSLstd450Reflect] = "Reflect";
|
||||
names[GLSLstd450Refract] = "Refract";
|
||||
names[GLSLstd450FindILsb] = "FindILsb";
|
||||
names[GLSLstd450FindSMsb] = "FindSMsb";
|
||||
names[GLSLstd450FindUMsb] = "FindUMsb";
|
||||
names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid";
|
||||
names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample";
|
||||
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
|
||||
names[GLSLstd450NMin] = "NMin";
|
||||
names[GLSLstd450NMax] = "NMax";
|
||||
names[GLSLstd450NClamp] = "NClamp";
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
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(name, spv::E_SPV_NVX_multiview_per_view_attributes) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_fragment_shader_barycentric) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_mesh_shader) == 0 ||
|
||||
strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) {
|
||||
switch (entrypoint) {
|
||||
// NV builtins
|
||||
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
||||
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||
case BuiltInTaskCountNV: return "TaskCountNV";
|
||||
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
|
||||
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
|
||||
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
|
||||
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
|
||||
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
|
||||
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||
|
||||
// NV Capabilities
|
||||
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
||||
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||
case CapabilityImageFootprintNV: return "ImageFootprintNV";
|
||||
case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
|
||||
|
||||
// NV Decorations
|
||||
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||
case DecorationPassthroughNV: return "PassthroughNV";
|
||||
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
||||
case DecorationPerVertexNV: return "PerVertexNV";
|
||||
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
|
||||
case DecorationPerViewNV: return "PerViewNV";
|
||||
case DecorationPerTaskNV: return "PerTaskNV";
|
||||
|
||||
default: return "Bad";
|
||||
}
|
||||
}
|
||||
return "Bad";
|
||||
}
|
||||
|
||||
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
||||
{
|
||||
SpirvStream SpirvStream(out, stream);
|
||||
spv::Parameterize();
|
||||
GLSLstd450GetDebugNames(GlslStd450DebugNames);
|
||||
SpirvStream.validate();
|
||||
SpirvStream.processInstructions();
|
||||
}
|
||||
|
||||
}; // end namespace spv
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014-2015 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.
|
||||
|
||||
//
|
||||
// Disassembler for SPIR-V.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef disassembler_H
|
||||
#define disassembler_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace spv {
|
||||
|
||||
// disassemble with glslang custom disassembler
|
||||
void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
||||
|
||||
} // end namespace spv
|
||||
|
||||
#endif // disassembler_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,258 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014-2015 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.
|
||||
|
||||
//
|
||||
// Parameterize the SPIR-V enumerants.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "spirv.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace spv {
|
||||
|
||||
// Fill in all the parameters
|
||||
void Parameterize();
|
||||
|
||||
// Return the English names of all the enums.
|
||||
const char* SourceString(int);
|
||||
const char* AddressingString(int);
|
||||
const char* MemoryString(int);
|
||||
const char* ExecutionModelString(int);
|
||||
const char* ExecutionModeString(int);
|
||||
const char* StorageClassString(int);
|
||||
const char* DecorationString(int);
|
||||
const char* BuiltInString(int);
|
||||
const char* DimensionString(int);
|
||||
const char* SelectControlString(int);
|
||||
const char* LoopControlString(int);
|
||||
const char* FunctionControlString(int);
|
||||
const char* SamplerAddressingModeString(int);
|
||||
const char* SamplerFilterModeString(int);
|
||||
const char* ImageFormatString(int);
|
||||
const char* ImageChannelOrderString(int);
|
||||
const char* ImageChannelTypeString(int);
|
||||
const char* ImageChannelDataTypeString(int type);
|
||||
const char* ImageOperandsString(int format);
|
||||
const char* ImageOperands(int);
|
||||
const char* FPFastMathString(int);
|
||||
const char* FPRoundingModeString(int);
|
||||
const char* LinkageTypeString(int);
|
||||
const char* FuncParamAttrString(int);
|
||||
const char* AccessQualifierString(int);
|
||||
const char* MemorySemanticsString(int);
|
||||
const char* MemoryAccessString(int);
|
||||
const char* ExecutionScopeString(int);
|
||||
const char* GroupOperationString(int);
|
||||
const char* KernelEnqueueFlagsString(int);
|
||||
const char* KernelProfilingInfoString(int);
|
||||
const char* CapabilityString(int);
|
||||
const char* OpcodeString(int);
|
||||
const char* ScopeString(int mem);
|
||||
|
||||
// For grouping opcodes into subsections
|
||||
enum OpcodeClass {
|
||||
OpClassMisc,
|
||||
OpClassDebug,
|
||||
OpClassAnnotate,
|
||||
OpClassExtension,
|
||||
OpClassMode,
|
||||
OpClassType,
|
||||
OpClassConstant,
|
||||
OpClassMemory,
|
||||
OpClassFunction,
|
||||
OpClassImage,
|
||||
OpClassConvert,
|
||||
OpClassComposite,
|
||||
OpClassArithmetic,
|
||||
OpClassBit,
|
||||
OpClassRelationalLogical,
|
||||
OpClassDerivative,
|
||||
OpClassFlowControl,
|
||||
OpClassAtomic,
|
||||
OpClassPrimitive,
|
||||
OpClassBarrier,
|
||||
OpClassGroup,
|
||||
OpClassDeviceSideEnqueue,
|
||||
OpClassPipe,
|
||||
|
||||
OpClassCount,
|
||||
OpClassMissing // all instructions start out as missing
|
||||
};
|
||||
|
||||
// For parameterizing operands.
|
||||
enum OperandClass {
|
||||
OperandNone,
|
||||
OperandId,
|
||||
OperandVariableIds,
|
||||
OperandOptionalLiteral,
|
||||
OperandOptionalLiteralString,
|
||||
OperandVariableLiterals,
|
||||
OperandVariableIdLiteral,
|
||||
OperandVariableLiteralId,
|
||||
OperandLiteralNumber,
|
||||
OperandLiteralString,
|
||||
OperandSource,
|
||||
OperandExecutionModel,
|
||||
OperandAddressing,
|
||||
OperandMemory,
|
||||
OperandExecutionMode,
|
||||
OperandStorage,
|
||||
OperandDimensionality,
|
||||
OperandSamplerAddressingMode,
|
||||
OperandSamplerFilterMode,
|
||||
OperandSamplerImageFormat,
|
||||
OperandImageChannelOrder,
|
||||
OperandImageChannelDataType,
|
||||
OperandImageOperands,
|
||||
OperandFPFastMath,
|
||||
OperandFPRoundingMode,
|
||||
OperandLinkageType,
|
||||
OperandAccessQualifier,
|
||||
OperandFuncParamAttr,
|
||||
OperandDecoration,
|
||||
OperandBuiltIn,
|
||||
OperandSelect,
|
||||
OperandLoop,
|
||||
OperandFunction,
|
||||
OperandMemorySemantics,
|
||||
OperandMemoryAccess,
|
||||
OperandScope,
|
||||
OperandGroupOperation,
|
||||
OperandKernelEnqueueFlags,
|
||||
OperandKernelProfilingInfo,
|
||||
OperandCapability,
|
||||
|
||||
OperandOpcode,
|
||||
|
||||
OperandCount
|
||||
};
|
||||
|
||||
// Any specific enum can have a set of capabilities that allow it:
|
||||
typedef std::vector<Capability> EnumCaps;
|
||||
|
||||
// Parameterize a set of operands with their OperandClass(es) and descriptions.
|
||||
class OperandParameters {
|
||||
public:
|
||||
OperandParameters() { }
|
||||
void push(OperandClass oc, const char* d, bool opt = false)
|
||||
{
|
||||
opClass.push_back(oc);
|
||||
desc.push_back(d);
|
||||
optional.push_back(opt);
|
||||
}
|
||||
void setOptional();
|
||||
OperandClass getClass(int op) const { return opClass[op]; }
|
||||
const char* getDesc(int op) const { return desc[op]; }
|
||||
bool isOptional(int op) const { return optional[op]; }
|
||||
int getNum() const { return (int)opClass.size(); }
|
||||
|
||||
protected:
|
||||
std::vector<OperandClass> opClass;
|
||||
std::vector<const char*> desc;
|
||||
std::vector<bool> optional;
|
||||
};
|
||||
|
||||
// Parameterize an enumerant
|
||||
class EnumParameters {
|
||||
public:
|
||||
EnumParameters() : desc(0) { }
|
||||
const char* desc;
|
||||
};
|
||||
|
||||
// Parameterize a set of enumerants that form an enum
|
||||
class EnumDefinition : public EnumParameters {
|
||||
public:
|
||||
EnumDefinition() :
|
||||
ceiling(0), bitmask(false), getName(0), enumParams(0), operandParams(0) { }
|
||||
void set(int ceil, const char* (*name)(int), EnumParameters* ep, bool mask = false)
|
||||
{
|
||||
ceiling = ceil;
|
||||
getName = name;
|
||||
bitmask = mask;
|
||||
enumParams = ep;
|
||||
}
|
||||
void setOperands(OperandParameters* op) { operandParams = op; }
|
||||
int ceiling; // ceiling of enumerants
|
||||
bool bitmask; // true if these enumerants combine into a bitmask
|
||||
const char* (*getName)(int); // a function that returns the name for each enumerant value (or shift)
|
||||
EnumParameters* enumParams; // parameters for each individual enumerant
|
||||
OperandParameters* operandParams; // sets of operands
|
||||
};
|
||||
|
||||
// Parameterize an instruction's logical format, including its known set of operands,
|
||||
// per OperandParameters above.
|
||||
class InstructionParameters {
|
||||
public:
|
||||
InstructionParameters() :
|
||||
opDesc("TBD"),
|
||||
opClass(OpClassMissing),
|
||||
typePresent(true), // most normal, only exceptions have to be spelled out
|
||||
resultPresent(true) // most normal, only exceptions have to be spelled out
|
||||
{ }
|
||||
|
||||
void setResultAndType(bool r, bool t)
|
||||
{
|
||||
resultPresent = r;
|
||||
typePresent = t;
|
||||
}
|
||||
|
||||
bool hasResult() const { return resultPresent != 0; }
|
||||
bool hasType() const { return typePresent != 0; }
|
||||
|
||||
const char* opDesc;
|
||||
OpcodeClass opClass;
|
||||
OperandParameters operands;
|
||||
|
||||
protected:
|
||||
int typePresent : 1;
|
||||
int resultPresent : 1;
|
||||
};
|
||||
|
||||
// The set of objects that hold all the instruction/operand
|
||||
// parameterization information.
|
||||
extern InstructionParameters InstructionDesc[];
|
||||
|
||||
// These hold definitions of the enumerants used for operands
|
||||
extern EnumDefinition OperandClassParams[];
|
||||
|
||||
const char* GetOperandDesc(OperandClass operand);
|
||||
void PrintImmediateRow(int imm, const char* name, const EnumParameters* enumParams, bool caps, bool hex = false);
|
||||
const char* AccessQualifierString(int attr);
|
||||
|
||||
void PrintOperands(const OperandParameters& operands, int reservedOperands);
|
||||
|
||||
} // end namespace spv
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,485 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2014 LunarG, Inc.
|
||||
// Copyright (C) 2015-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.
|
||||
|
||||
// SPIRV-IR
|
||||
//
|
||||
// Simple in-memory representation (IR) of SPIRV. Just for holding
|
||||
// Each function's CFG of blocks. Has this hierarchy:
|
||||
// - Module, which is a list of
|
||||
// - Function, which is a list of
|
||||
// - Block, which is a list of
|
||||
// - Instruction
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef spvIR_H
|
||||
#define spvIR_H
|
||||
|
||||
#include "spirv.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace spv {
|
||||
|
||||
class Block;
|
||||
class Function;
|
||||
class Module;
|
||||
|
||||
const Id NoResult = 0;
|
||||
const Id NoType = 0;
|
||||
|
||||
const Decoration NoPrecision = DecorationMax;
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define POTENTIALLY_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define POTENTIALLY_UNUSED
|
||||
#endif
|
||||
|
||||
POTENTIALLY_UNUSED
|
||||
const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||
(MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
|
||||
MemorySemanticsWorkgroupMemoryMask |
|
||||
MemorySemanticsAtomicCounterMemoryMask |
|
||||
MemorySemanticsImageMemoryMask);
|
||||
|
||||
struct IdImmediate {
|
||||
bool isId; // true if word is an Id, false if word is an immediate
|
||||
unsigned word;
|
||||
IdImmediate(bool i, unsigned w) : isId(i), word(w) {}
|
||||
};
|
||||
|
||||
//
|
||||
// SPIR-V IR instruction.
|
||||
//
|
||||
|
||||
class Instruction {
|
||||
public:
|
||||
Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }
|
||||
explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }
|
||||
virtual ~Instruction() {}
|
||||
void addIdOperand(Id id) {
|
||||
operands.push_back(id);
|
||||
idOperand.push_back(true);
|
||||
}
|
||||
void addImmediateOperand(unsigned int immediate) {
|
||||
operands.push_back(immediate);
|
||||
idOperand.push_back(false);
|
||||
}
|
||||
void setImmediateOperand(unsigned idx, unsigned int immediate) {
|
||||
assert(!idOperand[idx]);
|
||||
operands[idx] = immediate;
|
||||
}
|
||||
|
||||
void addStringOperand(const char* str)
|
||||
{
|
||||
unsigned int word;
|
||||
char* wordString = (char*)&word;
|
||||
char* wordPtr = wordString;
|
||||
int charCount = 0;
|
||||
char c;
|
||||
do {
|
||||
c = *(str++);
|
||||
*(wordPtr++) = c;
|
||||
++charCount;
|
||||
if (charCount == 4) {
|
||||
addImmediateOperand(word);
|
||||
wordPtr = wordString;
|
||||
charCount = 0;
|
||||
}
|
||||
} while (c != 0);
|
||||
|
||||
// deal with partial last word
|
||||
if (charCount > 0) {
|
||||
// pad with 0s
|
||||
for (; charCount < 4; ++charCount)
|
||||
*(wordPtr++) = 0;
|
||||
addImmediateOperand(word);
|
||||
}
|
||||
}
|
||||
bool isIdOperand(int op) const { return idOperand[op]; }
|
||||
void setBlock(Block* b) { block = b; }
|
||||
Block* getBlock() const { return block; }
|
||||
Op getOpCode() const { return opCode; }
|
||||
int getNumOperands() const
|
||||
{
|
||||
assert(operands.size() == idOperand.size());
|
||||
return (int)operands.size();
|
||||
}
|
||||
Id getResultId() const { return resultId; }
|
||||
Id getTypeId() const { return typeId; }
|
||||
Id getIdOperand(int op) const {
|
||||
assert(idOperand[op]);
|
||||
return operands[op];
|
||||
}
|
||||
unsigned int getImmediateOperand(int op) const {
|
||||
assert(!idOperand[op]);
|
||||
return operands[op];
|
||||
}
|
||||
|
||||
// Write out the binary form.
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
// Compute the wordCount
|
||||
unsigned int wordCount = 1;
|
||||
if (typeId)
|
||||
++wordCount;
|
||||
if (resultId)
|
||||
++wordCount;
|
||||
wordCount += (unsigned int)operands.size();
|
||||
|
||||
// Write out the beginning of the instruction
|
||||
out.push_back(((wordCount) << WordCountShift) | opCode);
|
||||
if (typeId)
|
||||
out.push_back(typeId);
|
||||
if (resultId)
|
||||
out.push_back(resultId);
|
||||
|
||||
// Write out the operands
|
||||
for (int op = 0; op < (int)operands.size(); ++op)
|
||||
out.push_back(operands[op]);
|
||||
}
|
||||
|
||||
protected:
|
||||
Instruction(const Instruction&);
|
||||
Id resultId;
|
||||
Id typeId;
|
||||
Op opCode;
|
||||
std::vector<Id> operands; // operands, both <id> and immediates (both are unsigned int)
|
||||
std::vector<bool> idOperand; // true for operands that are <id>, false for immediates
|
||||
Block* block;
|
||||
};
|
||||
|
||||
//
|
||||
// SPIR-V IR block.
|
||||
//
|
||||
|
||||
class Block {
|
||||
public:
|
||||
Block(Id id, Function& parent);
|
||||
virtual ~Block()
|
||||
{
|
||||
}
|
||||
|
||||
Id getId() { return instructions.front()->getResultId(); }
|
||||
|
||||
Function& getParent() const { return parent; }
|
||||
void addInstruction(std::unique_ptr<Instruction> inst);
|
||||
void addPredecessor(Block* pred) { predecessors.push_back(pred); pred->successors.push_back(this);}
|
||||
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
|
||||
const std::vector<Block*>& getPredecessors() const { return predecessors; }
|
||||
const std::vector<Block*>& getSuccessors() const { return successors; }
|
||||
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
||||
return instructions;
|
||||
}
|
||||
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
|
||||
void setUnreachable() { unreachable = true; }
|
||||
bool isUnreachable() const { return unreachable; }
|
||||
// Returns the block's merge instruction, if one exists (otherwise null).
|
||||
const Instruction* getMergeInstruction() const {
|
||||
if (instructions.size() < 2) return nullptr;
|
||||
const Instruction* nextToLast = (instructions.cend() - 2)->get();
|
||||
switch (nextToLast->getOpCode()) {
|
||||
case OpSelectionMerge:
|
||||
case OpLoopMerge:
|
||||
return nextToLast;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Change this block into a canonical dead merge block. Delete instructions
|
||||
// as necessary. A canonical dead merge block has only an OpLabel and an
|
||||
// OpUnreachable.
|
||||
void rewriteAsCanonicalUnreachableMerge() {
|
||||
assert(localVariables.empty());
|
||||
// Delete all instructions except for the label.
|
||||
assert(instructions.size() > 0);
|
||||
instructions.resize(1);
|
||||
successors.clear();
|
||||
addInstruction(std::unique_ptr<Instruction>(new Instruction(OpUnreachable)));
|
||||
}
|
||||
// Change this block into a canonical dead continue target branching to the
|
||||
// given header ID. Delete instructions as necessary. A canonical dead continue
|
||||
// target has only an OpLabel and an unconditional branch back to the corresponding
|
||||
// header.
|
||||
void rewriteAsCanonicalUnreachableContinue(Block* header) {
|
||||
assert(localVariables.empty());
|
||||
// Delete all instructions except for the label.
|
||||
assert(instructions.size() > 0);
|
||||
instructions.resize(1);
|
||||
successors.clear();
|
||||
// Add OpBranch back to the header.
|
||||
assert(header != nullptr);
|
||||
Instruction* branch = new Instruction(OpBranch);
|
||||
branch->addIdOperand(header->getId());
|
||||
addInstruction(std::unique_ptr<Instruction>(branch));
|
||||
successors.push_back(header);
|
||||
}
|
||||
|
||||
bool isTerminated() const
|
||||
{
|
||||
switch (instructions.back()->getOpCode()) {
|
||||
case OpBranch:
|
||||
case OpBranchConditional:
|
||||
case OpSwitch:
|
||||
case OpKill:
|
||||
case OpReturn:
|
||||
case OpReturnValue:
|
||||
case OpUnreachable:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
instructions[0]->dump(out);
|
||||
for (int i = 0; i < (int)localVariables.size(); ++i)
|
||||
localVariables[i]->dump(out);
|
||||
for (int i = 1; i < (int)instructions.size(); ++i)
|
||||
instructions[i]->dump(out);
|
||||
}
|
||||
|
||||
protected:
|
||||
Block(const Block&);
|
||||
Block& operator=(Block&);
|
||||
|
||||
// To enforce keeping parent and ownership in sync:
|
||||
friend Function;
|
||||
|
||||
std::vector<std::unique_ptr<Instruction> > instructions;
|
||||
std::vector<Block*> predecessors, successors;
|
||||
std::vector<std::unique_ptr<Instruction> > localVariables;
|
||||
Function& parent;
|
||||
|
||||
// track whether this block is known to be uncreachable (not necessarily
|
||||
// true for all unreachable blocks, but should be set at least
|
||||
// for the extraneous ones introduced by the builder).
|
||||
bool unreachable;
|
||||
};
|
||||
|
||||
// The different reasons for reaching a block in the inReadableOrder traversal.
|
||||
enum ReachReason {
|
||||
// Reachable from the entry block via transfers of control, i.e. branches.
|
||||
ReachViaControlFlow = 0,
|
||||
// A continue target that is not reachable via control flow.
|
||||
ReachDeadContinue,
|
||||
// A merge block that is not reachable via control flow.
|
||||
ReachDeadMerge
|
||||
};
|
||||
|
||||
// Traverses the control-flow graph rooted at root in an order suited for
|
||||
// readable code generation. Invokes callback at every node in the traversal
|
||||
// order. The callback arguments are:
|
||||
// - the block,
|
||||
// - the reason we reached the block,
|
||||
// - if the reason was that block is an unreachable continue or unreachable merge block
|
||||
// then the last parameter is the corresponding header block.
|
||||
void inReadableOrder(Block* root, std::function<void(Block*, ReachReason, Block* header)> callback);
|
||||
|
||||
//
|
||||
// SPIR-V IR Function.
|
||||
//
|
||||
|
||||
class Function {
|
||||
public:
|
||||
Function(Id id, Id resultType, Id functionType, Id firstParam, Module& parent);
|
||||
virtual ~Function()
|
||||
{
|
||||
for (int i = 0; i < (int)parameterInstructions.size(); ++i)
|
||||
delete parameterInstructions[i];
|
||||
|
||||
for (int i = 0; i < (int)blocks.size(); ++i)
|
||||
delete blocks[i];
|
||||
}
|
||||
Id getId() const { return functionInstruction.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 removeBlock(Block* block)
|
||||
{
|
||||
auto found = find(blocks.begin(), blocks.end(), block);
|
||||
assert(found != blocks.end());
|
||||
blocks.erase(found);
|
||||
delete block;
|
||||
}
|
||||
|
||||
Module& getParent() const { return parent; }
|
||||
Block* getEntryBlock() const { return blocks.front(); }
|
||||
Block* getLastBlock() const { return blocks.back(); }
|
||||
const std::vector<Block*>& getBlocks() const { return blocks; }
|
||||
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||
|
||||
void setImplicitThis() { implicitThis = true; }
|
||||
bool hasImplicitThis() const { return implicitThis; }
|
||||
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
// OpFunction
|
||||
functionInstruction.dump(out);
|
||||
|
||||
// OpFunctionParameter
|
||||
for (int p = 0; p < (int)parameterInstructions.size(); ++p)
|
||||
parameterInstructions[p]->dump(out);
|
||||
|
||||
// Blocks
|
||||
inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); });
|
||||
Instruction end(0, 0, OpFunctionEnd);
|
||||
end.dump(out);
|
||||
}
|
||||
|
||||
protected:
|
||||
Function(const Function&);
|
||||
Function& operator=(Function&);
|
||||
|
||||
Module& parent;
|
||||
Instruction functionInstruction;
|
||||
std::vector<Instruction*> parameterInstructions;
|
||||
std::vector<Block*> blocks;
|
||||
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
||||
};
|
||||
|
||||
//
|
||||
// SPIR-V IR Module.
|
||||
//
|
||||
|
||||
class Module {
|
||||
public:
|
||||
Module() {}
|
||||
virtual ~Module()
|
||||
{
|
||||
// TODO delete things
|
||||
}
|
||||
|
||||
void addFunction(Function *fun) { functions.push_back(fun); }
|
||||
|
||||
void mapInstruction(Instruction *instruction)
|
||||
{
|
||||
spv::Id resultId = instruction->getResultId();
|
||||
// map the instruction's result id
|
||||
if (resultId >= idToInstruction.size())
|
||||
idToInstruction.resize(resultId + 16);
|
||||
idToInstruction[resultId] = instruction;
|
||||
}
|
||||
|
||||
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
||||
const std::vector<Function*>& getFunctions() const { return functions; }
|
||||
spv::Id getTypeId(Id resultId) const {
|
||||
return idToInstruction[resultId] == nullptr ? NoType : idToInstruction[resultId]->getTypeId();
|
||||
}
|
||||
StorageClass getStorageClass(Id typeId) const
|
||||
{
|
||||
assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);
|
||||
return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0);
|
||||
}
|
||||
|
||||
void dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
for (int f = 0; f < (int)functions.size(); ++f)
|
||||
functions[f]->dump(out);
|
||||
}
|
||||
|
||||
protected:
|
||||
Module(const Module&);
|
||||
std::vector<Function*> functions;
|
||||
|
||||
// map from result id to instruction having that result id
|
||||
std::vector<Instruction*> idToInstruction;
|
||||
|
||||
// map from a result id to its type id
|
||||
};
|
||||
|
||||
//
|
||||
// Implementation (it's here due to circular type definitions).
|
||||
//
|
||||
|
||||
// Add both
|
||||
// - the OpFunction instruction
|
||||
// - all the OpFunctionParameter instructions
|
||||
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
||||
: parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false)
|
||||
{
|
||||
// OpFunction
|
||||
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
||||
functionInstruction.addIdOperand(functionType);
|
||||
parent.mapInstruction(&functionInstruction);
|
||||
parent.addFunction(this);
|
||||
|
||||
// OpFunctionParameter
|
||||
Instruction* typeInst = parent.getInstruction(functionType);
|
||||
int numParams = typeInst->getNumOperands() - 1;
|
||||
for (int p = 0; p < numParams; ++p) {
|
||||
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), OpFunctionParameter);
|
||||
parent.mapInstruction(param);
|
||||
parameterInstructions.push_back(param);
|
||||
}
|
||||
}
|
||||
|
||||
__inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)
|
||||
{
|
||||
Instruction* raw_instruction = inst.get();
|
||||
blocks[0]->addLocalVariable(std::move(inst));
|
||||
parent.mapInstruction(raw_instruction);
|
||||
}
|
||||
|
||||
__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)
|
||||
{
|
||||
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, OpLabel)));
|
||||
instructions.back()->setBlock(this);
|
||||
parent.getParent().mapInstruction(instructions.back().get());
|
||||
}
|
||||
|
||||
__inline void Block::addInstruction(std::unique_ptr<Instruction> inst)
|
||||
{
|
||||
Instruction* raw_instruction = inst.get();
|
||||
instructions.push_back(std::move(inst));
|
||||
raw_instruction->setBlock(this);
|
||||
if (raw_instruction->getResultId())
|
||||
parent.getParent().mapInstruction(raw_instruction);
|
||||
}
|
||||
|
||||
} // end spv namespace
|
||||
|
||||
#endif // spvIR_H
|
|
@ -1,68 +0,0 @@
|
|||
add_library(glslang-default-resource-limits
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resource_limits_c.cpp)
|
||||
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
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
|
||||
|
||||
|
||||
set(SOURCES StandAlone.cpp DirStackFileIncluder.h)
|
||||
|
||||
add_executable(glslangValidator ${SOURCES})
|
||||
set_property(TARGET glslangValidator PROPERTY FOLDER tools)
|
||||
glslang_set_link_args(glslangValidator)
|
||||
|
||||
set(LIBRARIES
|
||||
glslang
|
||||
SPIRV
|
||||
glslang-default-resource-limits)
|
||||
|
||||
if(ENABLE_SPVREMAPPER)
|
||||
set(LIBRARIES ${LIBRARIES} SPVRemapper)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(LIBRARIES ${LIBRARIES} psapi)
|
||||
elseif(UNIX)
|
||||
if(NOT ANDROID)
|
||||
set(LIBRARIES ${LIBRARIES} pthread)
|
||||
endif()
|
||||
endif(WIN32)
|
||||
|
||||
target_link_libraries(glslangValidator ${LIBRARIES})
|
||||
target_include_directories(glslangValidator PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../External>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/External>)
|
||||
|
||||
if(ENABLE_SPVREMAPPER)
|
||||
set(REMAPPER_SOURCES spirv-remap.cpp)
|
||||
add_executable(spirv-remap ${REMAPPER_SOURCES})
|
||||
set_property(TARGET spirv-remap PROPERTY FOLDER tools)
|
||||
glslang_set_link_args(spirv-remap)
|
||||
target_link_libraries(spirv-remap ${LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
source_group("Source" FILES ${SOURCES})
|
||||
endif(WIN32)
|
||||
|
||||
if(ENABLE_GLSLANG_INSTALL)
|
||||
install(TARGETS glslangValidator EXPORT glslangValidatorTargets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
install(EXPORT glslangValidatorTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
|
||||
if(ENABLE_SPVREMAPPER)
|
||||
install(TARGETS spirv-remap EXPORT spirv-remapTargets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
install(EXPORT spirv-remapTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
endif()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS glslang-default-resource-limits EXPORT glslang-default-resource-limitsTargets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(EXPORT glslang-default-resource-limitsTargets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
endif()
|
||||
endif(ENABLE_GLSLANG_INSTALL)
|
|
@ -1,141 +0,0 @@
|
|||
//
|
||||
// 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);
|
||||
}
|
||||
};
|
|
@ -1,494 +0,0 @@
|
|||
//
|
||||
// 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 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 <cstdlib>
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <cctype>
|
||||
|
||||
#include "ResourceLimits.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
const TBuiltInResource DefaultTBuiltInResource = {
|
||||
/* .MaxLights = */ 32,
|
||||
/* .MaxClipPlanes = */ 6,
|
||||
/* .MaxTextureUnits = */ 32,
|
||||
/* .MaxTextureCoords = */ 32,
|
||||
/* .MaxVertexAttribs = */ 64,
|
||||
/* .MaxVertexUniformComponents = */ 4096,
|
||||
/* .MaxVaryingFloats = */ 64,
|
||||
/* .MaxVertexTextureImageUnits = */ 32,
|
||||
/* .MaxCombinedTextureImageUnits = */ 80,
|
||||
/* .MaxTextureImageUnits = */ 32,
|
||||
/* .MaxFragmentUniformComponents = */ 4096,
|
||||
/* .MaxDrawBuffers = */ 32,
|
||||
/* .MaxVertexUniformVectors = */ 128,
|
||||
/* .MaxVaryingVectors = */ 8,
|
||||
/* .MaxFragmentUniformVectors = */ 16,
|
||||
/* .MaxVertexOutputVectors = */ 16,
|
||||
/* .MaxFragmentInputVectors = */ 15,
|
||||
/* .MinProgramTexelOffset = */ -8,
|
||||
/* .MaxProgramTexelOffset = */ 7,
|
||||
/* .MaxClipDistances = */ 8,
|
||||
/* .MaxComputeWorkGroupCountX = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountY = */ 65535,
|
||||
/* .MaxComputeWorkGroupCountZ = */ 65535,
|
||||
/* .MaxComputeWorkGroupSizeX = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeY = */ 1024,
|
||||
/* .MaxComputeWorkGroupSizeZ = */ 64,
|
||||
/* .MaxComputeUniformComponents = */ 1024,
|
||||
/* .MaxComputeTextureImageUnits = */ 16,
|
||||
/* .MaxComputeImageUniforms = */ 8,
|
||||
/* .MaxComputeAtomicCounters = */ 8,
|
||||
/* .MaxComputeAtomicCounterBuffers = */ 1,
|
||||
/* .MaxVaryingComponents = */ 60,
|
||||
/* .MaxVertexOutputComponents = */ 64,
|
||||
/* .MaxGeometryInputComponents = */ 64,
|
||||
/* .MaxGeometryOutputComponents = */ 128,
|
||||
/* .MaxFragmentInputComponents = */ 128,
|
||||
/* .MaxImageUnits = */ 8,
|
||||
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
||||
/* .MaxCombinedShaderOutputResources = */ 8,
|
||||
/* .MaxImageSamples = */ 0,
|
||||
/* .MaxVertexImageUniforms = */ 0,
|
||||
/* .MaxTessControlImageUniforms = */ 0,
|
||||
/* .MaxTessEvaluationImageUniforms = */ 0,
|
||||
/* .MaxGeometryImageUniforms = */ 0,
|
||||
/* .MaxFragmentImageUniforms = */ 8,
|
||||
/* .MaxCombinedImageUniforms = */ 8,
|
||||
/* .MaxGeometryTextureImageUnits = */ 16,
|
||||
/* .MaxGeometryOutputVertices = */ 256,
|
||||
/* .MaxGeometryTotalOutputComponents = */ 1024,
|
||||
/* .MaxGeometryUniformComponents = */ 1024,
|
||||
/* .MaxGeometryVaryingComponents = */ 64,
|
||||
/* .MaxTessControlInputComponents = */ 128,
|
||||
/* .MaxTessControlOutputComponents = */ 128,
|
||||
/* .MaxTessControlTextureImageUnits = */ 16,
|
||||
/* .MaxTessControlUniformComponents = */ 1024,
|
||||
/* .MaxTessControlTotalOutputComponents = */ 4096,
|
||||
/* .MaxTessEvaluationInputComponents = */ 128,
|
||||
/* .MaxTessEvaluationOutputComponents = */ 128,
|
||||
/* .MaxTessEvaluationTextureImageUnits = */ 16,
|
||||
/* .MaxTessEvaluationUniformComponents = */ 1024,
|
||||
/* .MaxTessPatchComponents = */ 120,
|
||||
/* .MaxPatchVertices = */ 32,
|
||||
/* .MaxTessGenLevel = */ 64,
|
||||
/* .MaxViewports = */ 16,
|
||||
/* .MaxVertexAtomicCounters = */ 0,
|
||||
/* .MaxTessControlAtomicCounters = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounters = */ 0,
|
||||
/* .MaxGeometryAtomicCounters = */ 0,
|
||||
/* .MaxFragmentAtomicCounters = */ 8,
|
||||
/* .MaxCombinedAtomicCounters = */ 8,
|
||||
/* .MaxAtomicCounterBindings = */ 1,
|
||||
/* .MaxVertexAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessControlAtomicCounterBuffers = */ 0,
|
||||
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
|
||||
/* .MaxGeometryAtomicCounterBuffers = */ 0,
|
||||
/* .MaxFragmentAtomicCounterBuffers = */ 1,
|
||||
/* .MaxCombinedAtomicCounterBuffers = */ 1,
|
||||
/* .MaxAtomicCounterBufferSize = */ 16384,
|
||||
/* .MaxTransformFeedbackBuffers = */ 4,
|
||||
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
|
||||
/* .MaxCullDistances = */ 8,
|
||||
/* .MaxCombinedClipAndCullDistances = */ 8,
|
||||
/* .MaxSamples = */ 4,
|
||||
/* .maxMeshOutputVerticesNV = */ 256,
|
||||
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||
/* .maxMeshViewCountNV = */ 4,
|
||||
|
||||
/* .limits = */ {
|
||||
/* .nonInductiveForLoops = */ 1,
|
||||
/* .whileLoops = */ 1,
|
||||
/* .doWhileLoops = */ 1,
|
||||
/* .generalUniformIndexing = */ 1,
|
||||
/* .generalAttributeMatrixVectorIndexing = */ 1,
|
||||
/* .generalVaryingIndexing = */ 1,
|
||||
/* .generalSamplerIndexing = */ 1,
|
||||
/* .generalVariableIndexing = */ 1,
|
||||
/* .generalConstantMatrixVectorIndexing = */ 1,
|
||||
}};
|
||||
|
||||
std::string GetDefaultTBuiltInResourceString()
|
||||
{
|
||||
std::ostringstream ostream;
|
||||
|
||||
ostream << "MaxLights " << DefaultTBuiltInResource.maxLights << "\n"
|
||||
<< "MaxClipPlanes " << DefaultTBuiltInResource.maxClipPlanes << "\n"
|
||||
<< "MaxTextureUnits " << DefaultTBuiltInResource.maxTextureUnits << "\n"
|
||||
<< "MaxTextureCoords " << DefaultTBuiltInResource.maxTextureCoords << "\n"
|
||||
<< "MaxVertexAttribs " << DefaultTBuiltInResource.maxVertexAttribs << "\n"
|
||||
<< "MaxVertexUniformComponents " << DefaultTBuiltInResource.maxVertexUniformComponents << "\n"
|
||||
<< "MaxVaryingFloats " << DefaultTBuiltInResource.maxVaryingFloats << "\n"
|
||||
<< "MaxVertexTextureImageUnits " << DefaultTBuiltInResource.maxVertexTextureImageUnits << "\n"
|
||||
<< "MaxCombinedTextureImageUnits " << DefaultTBuiltInResource.maxCombinedTextureImageUnits << "\n"
|
||||
<< "MaxTextureImageUnits " << DefaultTBuiltInResource.maxTextureImageUnits << "\n"
|
||||
<< "MaxFragmentUniformComponents " << DefaultTBuiltInResource.maxFragmentUniformComponents << "\n"
|
||||
<< "MaxDrawBuffers " << DefaultTBuiltInResource.maxDrawBuffers << "\n"
|
||||
<< "MaxVertexUniformVectors " << DefaultTBuiltInResource.maxVertexUniformVectors << "\n"
|
||||
<< "MaxVaryingVectors " << DefaultTBuiltInResource.maxVaryingVectors << "\n"
|
||||
<< "MaxFragmentUniformVectors " << DefaultTBuiltInResource.maxFragmentUniformVectors << "\n"
|
||||
<< "MaxVertexOutputVectors " << DefaultTBuiltInResource.maxVertexOutputVectors << "\n"
|
||||
<< "MaxFragmentInputVectors " << DefaultTBuiltInResource.maxFragmentInputVectors << "\n"
|
||||
<< "MinProgramTexelOffset " << DefaultTBuiltInResource.minProgramTexelOffset << "\n"
|
||||
<< "MaxProgramTexelOffset " << DefaultTBuiltInResource.maxProgramTexelOffset << "\n"
|
||||
<< "MaxClipDistances " << DefaultTBuiltInResource.maxClipDistances << "\n"
|
||||
<< "MaxComputeWorkGroupCountX " << DefaultTBuiltInResource.maxComputeWorkGroupCountX << "\n"
|
||||
<< "MaxComputeWorkGroupCountY " << DefaultTBuiltInResource.maxComputeWorkGroupCountY << "\n"
|
||||
<< "MaxComputeWorkGroupCountZ " << DefaultTBuiltInResource.maxComputeWorkGroupCountZ << "\n"
|
||||
<< "MaxComputeWorkGroupSizeX " << DefaultTBuiltInResource.maxComputeWorkGroupSizeX << "\n"
|
||||
<< "MaxComputeWorkGroupSizeY " << DefaultTBuiltInResource.maxComputeWorkGroupSizeY << "\n"
|
||||
<< "MaxComputeWorkGroupSizeZ " << DefaultTBuiltInResource.maxComputeWorkGroupSizeZ << "\n"
|
||||
<< "MaxComputeUniformComponents " << DefaultTBuiltInResource.maxComputeUniformComponents << "\n"
|
||||
<< "MaxComputeTextureImageUnits " << DefaultTBuiltInResource.maxComputeTextureImageUnits << "\n"
|
||||
<< "MaxComputeImageUniforms " << DefaultTBuiltInResource.maxComputeImageUniforms << "\n"
|
||||
<< "MaxComputeAtomicCounters " << DefaultTBuiltInResource.maxComputeAtomicCounters << "\n"
|
||||
<< "MaxComputeAtomicCounterBuffers " << DefaultTBuiltInResource.maxComputeAtomicCounterBuffers << "\n"
|
||||
<< "MaxVaryingComponents " << DefaultTBuiltInResource.maxVaryingComponents << "\n"
|
||||
<< "MaxVertexOutputComponents " << DefaultTBuiltInResource.maxVertexOutputComponents << "\n"
|
||||
<< "MaxGeometryInputComponents " << DefaultTBuiltInResource.maxGeometryInputComponents << "\n"
|
||||
<< "MaxGeometryOutputComponents " << DefaultTBuiltInResource.maxGeometryOutputComponents << "\n"
|
||||
<< "MaxFragmentInputComponents " << DefaultTBuiltInResource.maxFragmentInputComponents << "\n"
|
||||
<< "MaxImageUnits " << DefaultTBuiltInResource.maxImageUnits << "\n"
|
||||
<< "MaxCombinedImageUnitsAndFragmentOutputs " << DefaultTBuiltInResource.maxCombinedImageUnitsAndFragmentOutputs << "\n"
|
||||
<< "MaxCombinedShaderOutputResources " << DefaultTBuiltInResource.maxCombinedShaderOutputResources << "\n"
|
||||
<< "MaxImageSamples " << DefaultTBuiltInResource.maxImageSamples << "\n"
|
||||
<< "MaxVertexImageUniforms " << DefaultTBuiltInResource.maxVertexImageUniforms << "\n"
|
||||
<< "MaxTessControlImageUniforms " << DefaultTBuiltInResource.maxTessControlImageUniforms << "\n"
|
||||
<< "MaxTessEvaluationImageUniforms " << DefaultTBuiltInResource.maxTessEvaluationImageUniforms << "\n"
|
||||
<< "MaxGeometryImageUniforms " << DefaultTBuiltInResource.maxGeometryImageUniforms << "\n"
|
||||
<< "MaxFragmentImageUniforms " << DefaultTBuiltInResource.maxFragmentImageUniforms << "\n"
|
||||
<< "MaxCombinedImageUniforms " << DefaultTBuiltInResource.maxCombinedImageUniforms << "\n"
|
||||
<< "MaxGeometryTextureImageUnits " << DefaultTBuiltInResource.maxGeometryTextureImageUnits << "\n"
|
||||
<< "MaxGeometryOutputVertices " << DefaultTBuiltInResource.maxGeometryOutputVertices << "\n"
|
||||
<< "MaxGeometryTotalOutputComponents " << DefaultTBuiltInResource.maxGeometryTotalOutputComponents << "\n"
|
||||
<< "MaxGeometryUniformComponents " << DefaultTBuiltInResource.maxGeometryUniformComponents << "\n"
|
||||
<< "MaxGeometryVaryingComponents " << DefaultTBuiltInResource.maxGeometryVaryingComponents << "\n"
|
||||
<< "MaxTessControlInputComponents " << DefaultTBuiltInResource.maxTessControlInputComponents << "\n"
|
||||
<< "MaxTessControlOutputComponents " << DefaultTBuiltInResource.maxTessControlOutputComponents << "\n"
|
||||
<< "MaxTessControlTextureImageUnits " << DefaultTBuiltInResource.maxTessControlTextureImageUnits << "\n"
|
||||
<< "MaxTessControlUniformComponents " << DefaultTBuiltInResource.maxTessControlUniformComponents << "\n"
|
||||
<< "MaxTessControlTotalOutputComponents " << DefaultTBuiltInResource.maxTessControlTotalOutputComponents << "\n"
|
||||
<< "MaxTessEvaluationInputComponents " << DefaultTBuiltInResource.maxTessEvaluationInputComponents << "\n"
|
||||
<< "MaxTessEvaluationOutputComponents " << DefaultTBuiltInResource.maxTessEvaluationOutputComponents << "\n"
|
||||
<< "MaxTessEvaluationTextureImageUnits " << DefaultTBuiltInResource.maxTessEvaluationTextureImageUnits << "\n"
|
||||
<< "MaxTessEvaluationUniformComponents " << DefaultTBuiltInResource.maxTessEvaluationUniformComponents << "\n"
|
||||
<< "MaxTessPatchComponents " << DefaultTBuiltInResource.maxTessPatchComponents << "\n"
|
||||
<< "MaxPatchVertices " << DefaultTBuiltInResource.maxPatchVertices << "\n"
|
||||
<< "MaxTessGenLevel " << DefaultTBuiltInResource.maxTessGenLevel << "\n"
|
||||
<< "MaxViewports " << DefaultTBuiltInResource.maxViewports << "\n"
|
||||
<< "MaxVertexAtomicCounters " << DefaultTBuiltInResource.maxVertexAtomicCounters << "\n"
|
||||
<< "MaxTessControlAtomicCounters " << DefaultTBuiltInResource.maxTessControlAtomicCounters << "\n"
|
||||
<< "MaxTessEvaluationAtomicCounters " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounters << "\n"
|
||||
<< "MaxGeometryAtomicCounters " << DefaultTBuiltInResource.maxGeometryAtomicCounters << "\n"
|
||||
<< "MaxFragmentAtomicCounters " << DefaultTBuiltInResource.maxFragmentAtomicCounters << "\n"
|
||||
<< "MaxCombinedAtomicCounters " << DefaultTBuiltInResource.maxCombinedAtomicCounters << "\n"
|
||||
<< "MaxAtomicCounterBindings " << DefaultTBuiltInResource.maxAtomicCounterBindings << "\n"
|
||||
<< "MaxVertexAtomicCounterBuffers " << DefaultTBuiltInResource.maxVertexAtomicCounterBuffers << "\n"
|
||||
<< "MaxTessControlAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessControlAtomicCounterBuffers << "\n"
|
||||
<< "MaxTessEvaluationAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounterBuffers << "\n"
|
||||
<< "MaxGeometryAtomicCounterBuffers " << DefaultTBuiltInResource.maxGeometryAtomicCounterBuffers << "\n"
|
||||
<< "MaxFragmentAtomicCounterBuffers " << DefaultTBuiltInResource.maxFragmentAtomicCounterBuffers << "\n"
|
||||
<< "MaxCombinedAtomicCounterBuffers " << DefaultTBuiltInResource.maxCombinedAtomicCounterBuffers << "\n"
|
||||
<< "MaxAtomicCounterBufferSize " << DefaultTBuiltInResource.maxAtomicCounterBufferSize << "\n"
|
||||
<< "MaxTransformFeedbackBuffers " << DefaultTBuiltInResource.maxTransformFeedbackBuffers << "\n"
|
||||
<< "MaxTransformFeedbackInterleavedComponents " << DefaultTBuiltInResource.maxTransformFeedbackInterleavedComponents << "\n"
|
||||
<< "MaxCullDistances " << DefaultTBuiltInResource.maxCullDistances << "\n"
|
||||
<< "MaxCombinedClipAndCullDistances " << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n"
|
||||
<< "MaxSamples " << DefaultTBuiltInResource.maxSamples << "\n"
|
||||
<< "MaxMeshOutputVerticesNV " << DefaultTBuiltInResource.maxMeshOutputVerticesNV << "\n"
|
||||
<< "MaxMeshOutputPrimitivesNV " << DefaultTBuiltInResource.maxMeshOutputPrimitivesNV << "\n"
|
||||
<< "MaxMeshWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeX_NV << "\n"
|
||||
<< "MaxMeshWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeY_NV << "\n"
|
||||
<< "MaxMeshWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeZ_NV << "\n"
|
||||
<< "MaxTaskWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeX_NV << "\n"
|
||||
<< "MaxTaskWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n"
|
||||
<< "MaxTaskWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n"
|
||||
<< "MaxMeshViewCountNV " << DefaultTBuiltInResource.maxMeshViewCountNV << "\n"
|
||||
<< "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n"
|
||||
<< "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n"
|
||||
<< "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n"
|
||||
<< "generalUniformIndexing " << DefaultTBuiltInResource.limits.generalUniformIndexing << "\n"
|
||||
<< "generalAttributeMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalAttributeMatrixVectorIndexing << "\n"
|
||||
<< "generalVaryingIndexing " << DefaultTBuiltInResource.limits.generalVaryingIndexing << "\n"
|
||||
<< "generalSamplerIndexing " << DefaultTBuiltInResource.limits.generalSamplerIndexing << "\n"
|
||||
<< "generalVariableIndexing " << DefaultTBuiltInResource.limits.generalVariableIndexing << "\n"
|
||||
<< "generalConstantMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalConstantMatrixVectorIndexing << "\n"
|
||||
;
|
||||
|
||||
return ostream.str();
|
||||
}
|
||||
|
||||
void DecodeResourceLimits(TBuiltInResource* resources, char* config)
|
||||
{
|
||||
static const char* delims = " \t\n\r";
|
||||
|
||||
size_t pos = 0;
|
||||
std::string configStr(config);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const int value = std::atoi(valueStr.c_str());
|
||||
|
||||
if (tokenStr == "MaxLights")
|
||||
resources->maxLights = value;
|
||||
else if (tokenStr == "MaxClipPlanes")
|
||||
resources->maxClipPlanes = value;
|
||||
else if (tokenStr == "MaxTextureUnits")
|
||||
resources->maxTextureUnits = value;
|
||||
else if (tokenStr == "MaxTextureCoords")
|
||||
resources->maxTextureCoords = value;
|
||||
else if (tokenStr == "MaxVertexAttribs")
|
||||
resources->maxVertexAttribs = value;
|
||||
else if (tokenStr == "MaxVertexUniformComponents")
|
||||
resources->maxVertexUniformComponents = value;
|
||||
else if (tokenStr == "MaxVaryingFloats")
|
||||
resources->maxVaryingFloats = value;
|
||||
else if (tokenStr == "MaxVertexTextureImageUnits")
|
||||
resources->maxVertexTextureImageUnits = value;
|
||||
else if (tokenStr == "MaxCombinedTextureImageUnits")
|
||||
resources->maxCombinedTextureImageUnits = value;
|
||||
else if (tokenStr == "MaxTextureImageUnits")
|
||||
resources->maxTextureImageUnits = value;
|
||||
else if (tokenStr == "MaxFragmentUniformComponents")
|
||||
resources->maxFragmentUniformComponents = value;
|
||||
else if (tokenStr == "MaxDrawBuffers")
|
||||
resources->maxDrawBuffers = value;
|
||||
else if (tokenStr == "MaxVertexUniformVectors")
|
||||
resources->maxVertexUniformVectors = value;
|
||||
else if (tokenStr == "MaxVaryingVectors")
|
||||
resources->maxVaryingVectors = value;
|
||||
else if (tokenStr == "MaxFragmentUniformVectors")
|
||||
resources->maxFragmentUniformVectors = value;
|
||||
else if (tokenStr == "MaxVertexOutputVectors")
|
||||
resources->maxVertexOutputVectors = value;
|
||||
else if (tokenStr == "MaxFragmentInputVectors")
|
||||
resources->maxFragmentInputVectors = value;
|
||||
else if (tokenStr == "MinProgramTexelOffset")
|
||||
resources->minProgramTexelOffset = value;
|
||||
else if (tokenStr == "MaxProgramTexelOffset")
|
||||
resources->maxProgramTexelOffset = value;
|
||||
else if (tokenStr == "MaxClipDistances")
|
||||
resources->maxClipDistances = value;
|
||||
else if (tokenStr == "MaxComputeWorkGroupCountX")
|
||||
resources->maxComputeWorkGroupCountX = value;
|
||||
else if (tokenStr == "MaxComputeWorkGroupCountY")
|
||||
resources->maxComputeWorkGroupCountY = value;
|
||||
else if (tokenStr == "MaxComputeWorkGroupCountZ")
|
||||
resources->maxComputeWorkGroupCountZ = value;
|
||||
else if (tokenStr == "MaxComputeWorkGroupSizeX")
|
||||
resources->maxComputeWorkGroupSizeX = value;
|
||||
else if (tokenStr == "MaxComputeWorkGroupSizeY")
|
||||
resources->maxComputeWorkGroupSizeY = value;
|
||||
else if (tokenStr == "MaxComputeWorkGroupSizeZ")
|
||||
resources->maxComputeWorkGroupSizeZ = value;
|
||||
else if (tokenStr == "MaxComputeUniformComponents")
|
||||
resources->maxComputeUniformComponents = value;
|
||||
else if (tokenStr == "MaxComputeTextureImageUnits")
|
||||
resources->maxComputeTextureImageUnits = value;
|
||||
else if (tokenStr == "MaxComputeImageUniforms")
|
||||
resources->maxComputeImageUniforms = value;
|
||||
else if (tokenStr == "MaxComputeAtomicCounters")
|
||||
resources->maxComputeAtomicCounters = value;
|
||||
else if (tokenStr == "MaxComputeAtomicCounterBuffers")
|
||||
resources->maxComputeAtomicCounterBuffers = value;
|
||||
else if (tokenStr == "MaxVaryingComponents")
|
||||
resources->maxVaryingComponents = value;
|
||||
else if (tokenStr == "MaxVertexOutputComponents")
|
||||
resources->maxVertexOutputComponents = value;
|
||||
else if (tokenStr == "MaxGeometryInputComponents")
|
||||
resources->maxGeometryInputComponents = value;
|
||||
else if (tokenStr == "MaxGeometryOutputComponents")
|
||||
resources->maxGeometryOutputComponents = value;
|
||||
else if (tokenStr == "MaxFragmentInputComponents")
|
||||
resources->maxFragmentInputComponents = value;
|
||||
else if (tokenStr == "MaxImageUnits")
|
||||
resources->maxImageUnits = value;
|
||||
else if (tokenStr == "MaxCombinedImageUnitsAndFragmentOutputs")
|
||||
resources->maxCombinedImageUnitsAndFragmentOutputs = value;
|
||||
else if (tokenStr == "MaxCombinedShaderOutputResources")
|
||||
resources->maxCombinedShaderOutputResources = value;
|
||||
else if (tokenStr == "MaxImageSamples")
|
||||
resources->maxImageSamples = value;
|
||||
else if (tokenStr == "MaxVertexImageUniforms")
|
||||
resources->maxVertexImageUniforms = value;
|
||||
else if (tokenStr == "MaxTessControlImageUniforms")
|
||||
resources->maxTessControlImageUniforms = value;
|
||||
else if (tokenStr == "MaxTessEvaluationImageUniforms")
|
||||
resources->maxTessEvaluationImageUniforms = value;
|
||||
else if (tokenStr == "MaxGeometryImageUniforms")
|
||||
resources->maxGeometryImageUniforms = value;
|
||||
else if (tokenStr == "MaxFragmentImageUniforms")
|
||||
resources->maxFragmentImageUniforms = value;
|
||||
else if (tokenStr == "MaxCombinedImageUniforms")
|
||||
resources->maxCombinedImageUniforms = value;
|
||||
else if (tokenStr == "MaxGeometryTextureImageUnits")
|
||||
resources->maxGeometryTextureImageUnits = value;
|
||||
else if (tokenStr == "MaxGeometryOutputVertices")
|
||||
resources->maxGeometryOutputVertices = value;
|
||||
else if (tokenStr == "MaxGeometryTotalOutputComponents")
|
||||
resources->maxGeometryTotalOutputComponents = value;
|
||||
else if (tokenStr == "MaxGeometryUniformComponents")
|
||||
resources->maxGeometryUniformComponents = value;
|
||||
else if (tokenStr == "MaxGeometryVaryingComponents")
|
||||
resources->maxGeometryVaryingComponents = value;
|
||||
else if (tokenStr == "MaxTessControlInputComponents")
|
||||
resources->maxTessControlInputComponents = value;
|
||||
else if (tokenStr == "MaxTessControlOutputComponents")
|
||||
resources->maxTessControlOutputComponents = value;
|
||||
else if (tokenStr == "MaxTessControlTextureImageUnits")
|
||||
resources->maxTessControlTextureImageUnits = value;
|
||||
else if (tokenStr == "MaxTessControlUniformComponents")
|
||||
resources->maxTessControlUniformComponents = value;
|
||||
else if (tokenStr == "MaxTessControlTotalOutputComponents")
|
||||
resources->maxTessControlTotalOutputComponents = value;
|
||||
else if (tokenStr == "MaxTessEvaluationInputComponents")
|
||||
resources->maxTessEvaluationInputComponents = value;
|
||||
else if (tokenStr == "MaxTessEvaluationOutputComponents")
|
||||
resources->maxTessEvaluationOutputComponents = value;
|
||||
else if (tokenStr == "MaxTessEvaluationTextureImageUnits")
|
||||
resources->maxTessEvaluationTextureImageUnits = value;
|
||||
else if (tokenStr == "MaxTessEvaluationUniformComponents")
|
||||
resources->maxTessEvaluationUniformComponents = value;
|
||||
else if (tokenStr == "MaxTessPatchComponents")
|
||||
resources->maxTessPatchComponents = value;
|
||||
else if (tokenStr == "MaxPatchVertices")
|
||||
resources->maxPatchVertices = value;
|
||||
else if (tokenStr == "MaxTessGenLevel")
|
||||
resources->maxTessGenLevel = value;
|
||||
else if (tokenStr == "MaxViewports")
|
||||
resources->maxViewports = value;
|
||||
else if (tokenStr == "MaxVertexAtomicCounters")
|
||||
resources->maxVertexAtomicCounters = value;
|
||||
else if (tokenStr == "MaxTessControlAtomicCounters")
|
||||
resources->maxTessControlAtomicCounters = value;
|
||||
else if (tokenStr == "MaxTessEvaluationAtomicCounters")
|
||||
resources->maxTessEvaluationAtomicCounters = value;
|
||||
else if (tokenStr == "MaxGeometryAtomicCounters")
|
||||
resources->maxGeometryAtomicCounters = value;
|
||||
else if (tokenStr == "MaxFragmentAtomicCounters")
|
||||
resources->maxFragmentAtomicCounters = value;
|
||||
else if (tokenStr == "MaxCombinedAtomicCounters")
|
||||
resources->maxCombinedAtomicCounters = value;
|
||||
else if (tokenStr == "MaxAtomicCounterBindings")
|
||||
resources->maxAtomicCounterBindings = value;
|
||||
else if (tokenStr == "MaxVertexAtomicCounterBuffers")
|
||||
resources->maxVertexAtomicCounterBuffers = value;
|
||||
else if (tokenStr == "MaxTessControlAtomicCounterBuffers")
|
||||
resources->maxTessControlAtomicCounterBuffers = value;
|
||||
else if (tokenStr == "MaxTessEvaluationAtomicCounterBuffers")
|
||||
resources->maxTessEvaluationAtomicCounterBuffers = value;
|
||||
else if (tokenStr == "MaxGeometryAtomicCounterBuffers")
|
||||
resources->maxGeometryAtomicCounterBuffers = value;
|
||||
else if (tokenStr == "MaxFragmentAtomicCounterBuffers")
|
||||
resources->maxFragmentAtomicCounterBuffers = value;
|
||||
else if (tokenStr == "MaxCombinedAtomicCounterBuffers")
|
||||
resources->maxCombinedAtomicCounterBuffers = value;
|
||||
else if (tokenStr == "MaxAtomicCounterBufferSize")
|
||||
resources->maxAtomicCounterBufferSize = value;
|
||||
else if (tokenStr == "MaxTransformFeedbackBuffers")
|
||||
resources->maxTransformFeedbackBuffers = value;
|
||||
else if (tokenStr == "MaxTransformFeedbackInterleavedComponents")
|
||||
resources->maxTransformFeedbackInterleavedComponents = value;
|
||||
else if (tokenStr == "MaxCullDistances")
|
||||
resources->maxCullDistances = value;
|
||||
else if (tokenStr == "MaxCombinedClipAndCullDistances")
|
||||
resources->maxCombinedClipAndCullDistances = value;
|
||||
else if (tokenStr == "MaxSamples")
|
||||
resources->maxSamples = value;
|
||||
else if (tokenStr == "MaxMeshOutputVerticesNV")
|
||||
resources->maxMeshOutputVerticesNV = value;
|
||||
else if (tokenStr == "MaxMeshOutputPrimitivesNV")
|
||||
resources->maxMeshOutputPrimitivesNV = value;
|
||||
else if (tokenStr == "MaxMeshWorkGroupSizeX_NV")
|
||||
resources->maxMeshWorkGroupSizeX_NV = value;
|
||||
else if (tokenStr == "MaxMeshWorkGroupSizeY_NV")
|
||||
resources->maxMeshWorkGroupSizeY_NV = value;
|
||||
else if (tokenStr == "MaxMeshWorkGroupSizeZ_NV")
|
||||
resources->maxMeshWorkGroupSizeZ_NV = value;
|
||||
else if (tokenStr == "MaxTaskWorkGroupSizeX_NV")
|
||||
resources->maxTaskWorkGroupSizeX_NV = value;
|
||||
else if (tokenStr == "MaxTaskWorkGroupSizeY_NV")
|
||||
resources->maxTaskWorkGroupSizeY_NV = value;
|
||||
else if (tokenStr == "MaxTaskWorkGroupSizeZ_NV")
|
||||
resources->maxTaskWorkGroupSizeZ_NV = value;
|
||||
else if (tokenStr == "MaxMeshViewCountNV")
|
||||
resources->maxMeshViewCountNV = value;
|
||||
else if (tokenStr == "nonInductiveForLoops")
|
||||
resources->limits.nonInductiveForLoops = (value != 0);
|
||||
else if (tokenStr == "whileLoops")
|
||||
resources->limits.whileLoops = (value != 0);
|
||||
else if (tokenStr == "doWhileLoops")
|
||||
resources->limits.doWhileLoops = (value != 0);
|
||||
else if (tokenStr == "generalUniformIndexing")
|
||||
resources->limits.generalUniformIndexing = (value != 0);
|
||||
else if (tokenStr == "generalAttributeMatrixVectorIndexing")
|
||||
resources->limits.generalAttributeMatrixVectorIndexing = (value != 0);
|
||||
else if (tokenStr == "generalVaryingIndexing")
|
||||
resources->limits.generalVaryingIndexing = (value != 0);
|
||||
else if (tokenStr == "generalSamplerIndexing")
|
||||
resources->limits.generalSamplerIndexing = (value != 0);
|
||||
else if (tokenStr == "generalVariableIndexing")
|
||||
resources->limits.generalVariableIndexing = (value != 0);
|
||||
else if (tokenStr == "generalConstantMatrixVectorIndexing")
|
||||
resources->limits.generalConstantMatrixVectorIndexing = (value != 0);
|
||||
else
|
||||
printf("Warning: unrecognized limit (%s) in configuration file.\n", tokenStr.c_str());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
|
@ -1,57 +0,0 @@
|
|||
//
|
||||
// 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 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.
|
||||
|
||||
#ifndef _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
|
||||
#define _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../glslang/Include/ResourceLimits.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
// These are the default resources for TBuiltInResources, used for both
|
||||
// - parsing this string for the case where the user didn't supply one,
|
||||
// - dumping out a template for user construction of a config file.
|
||||
extern const TBuiltInResource DefaultTBuiltInResource;
|
||||
|
||||
// Returns the DefaultTBuiltInResource as a human-readable string.
|
||||
std::string GetDefaultTBuiltInResourceString();
|
||||
|
||||
// Decodes the resource limits from |config| to |resources|.
|
||||
void DecodeResourceLimits(TBuiltInResource* resources, char* config);
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_
|
File diff suppressed because it is too large
Load Diff
|
@ -1,95 +0,0 @@
|
|||
//
|
||||
// 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.
|
||||
//
|
||||
#ifndef WORKLIST_H_INCLUDED
|
||||
#define WORKLIST_H_INCLUDED
|
||||
|
||||
#include "../glslang/OSDependent/osinclude.h"
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TWorkItem {
|
||||
public:
|
||||
TWorkItem() { }
|
||||
explicit TWorkItem(const std::string& s) :
|
||||
name(s) { }
|
||||
std::string name;
|
||||
std::string results;
|
||||
std::string resultsIndex;
|
||||
};
|
||||
|
||||
class TWorklist {
|
||||
public:
|
||||
TWorklist() { }
|
||||
virtual ~TWorklist() { }
|
||||
|
||||
void add(TWorkItem* item)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex);
|
||||
worklist.push_back(item);
|
||||
}
|
||||
|
||||
bool remove(TWorkItem*& item)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex);
|
||||
|
||||
if (worklist.empty())
|
||||
return false;
|
||||
item = worklist.front();
|
||||
worklist.pop_front();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
return (int)worklist.size();
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return worklist.empty();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::mutex mutex;
|
||||
std::list<TWorkItem*> worklist;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // WORKLIST_H_INCLUDED
|
|
@ -1,65 +0,0 @@
|
|||
/**
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2020, Travis Fort
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. 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.
|
||||
|
||||
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 HOLDER 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 "resource_limits_c.h"
|
||||
#include "ResourceLimits.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
const glslang_resource_t* glslang_default_resource(void)
|
||||
{
|
||||
return reinterpret_cast<const glslang_resource_t*>(&glslang::DefaultTBuiltInResource);
|
||||
}
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
const char* glslang_default_resource_string()
|
||||
{
|
||||
std::string cpp_str = glslang::GetDefaultTBuiltInResourceString();
|
||||
char* c_str = (char*)malloc(cpp_str.length() + 1);
|
||||
strcpy(c_str, cpp_str.c_str());
|
||||
return c_str;
|
||||
}
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
void glslang_decode_resource_limits(glslang_resource_t* resources, char* config)
|
||||
{
|
||||
glslang::DecodeResourceLimits(reinterpret_cast<TBuiltInResource*>(resources), config);
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/**
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2020, Travis Fort
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. 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.
|
||||
|
||||
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 HOLDER 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 _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
|
||||
#define _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
|
||||
|
||||
#include "../glslang/Include/glslang_c_interface.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// These are the default resources for TBuiltInResources, used for both
|
||||
// - parsing this string for the case where the user didn't supply one,
|
||||
// - dumping out a template for user construction of a config file.
|
||||
const glslang_resource_t* glslang_default_resource(void);
|
||||
|
||||
// Returns the DefaultTBuiltInResource as a human-readable string.
|
||||
// NOTE: User is responsible for freeing this string.
|
||||
const char* glslang_default_resource_string();
|
||||
|
||||
// Decodes the resource limits from |config| to |resources|.
|
||||
void glslang_decode_resource_limits(glslang_resource_t* resources, char* config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _STAND_ALONE_RESOURCE_LIMITS_C_INCLUDED_
|
|
@ -1,341 +0,0 @@
|
|||
//
|
||||
// Copyright (C) 2015 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 <iostream>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../SPIRV/SPVRemapper.h"
|
||||
|
||||
namespace {
|
||||
|
||||
typedef unsigned int SpvWord;
|
||||
|
||||
// Poor man's basename: given a complete path, return file portion.
|
||||
// E.g:
|
||||
// Linux: /foo/bar/test -> test
|
||||
// Win: c:\foo\bar\test -> test
|
||||
// It's not very efficient, but that doesn't matter for our minimal-duty use.
|
||||
// Using boost::filesystem would be better in many ways, but want to avoid that dependency.
|
||||
|
||||
// OS dependent path separator (avoiding boost::filesystem dependency)
|
||||
#if defined(_WIN32)
|
||||
char path_sep_char() { return '\\'; }
|
||||
#else
|
||||
char path_sep_char() { return '/'; }
|
||||
#endif
|
||||
|
||||
std::string basename(const std::string filename)
|
||||
{
|
||||
const size_t sepLoc = filename.find_last_of(path_sep_char());
|
||||
|
||||
return (sepLoc == filename.npos) ? filename : filename.substr(sepLoc+1);
|
||||
}
|
||||
|
||||
void errHandler(const std::string& str) {
|
||||
std::cout << str << std::endl;
|
||||
exit(5);
|
||||
}
|
||||
|
||||
void logHandler(const std::string& str) {
|
||||
std::cout << str << std::endl;
|
||||
}
|
||||
|
||||
// Read word stream from disk
|
||||
void read(std::vector<SpvWord>& spv, const std::string& inFilename, int verbosity)
|
||||
{
|
||||
std::ifstream fp;
|
||||
|
||||
if (verbosity > 0)
|
||||
logHandler(std::string(" reading: ") + inFilename);
|
||||
|
||||
spv.clear();
|
||||
fp.open(inFilename, std::fstream::in | std::fstream::binary);
|
||||
|
||||
if (fp.fail())
|
||||
errHandler("error opening file for read: ");
|
||||
|
||||
// Reserve space (for efficiency, not for correctness)
|
||||
fp.seekg(0, fp.end);
|
||||
spv.reserve(size_t(fp.tellg()) / sizeof(SpvWord));
|
||||
fp.seekg(0, fp.beg);
|
||||
|
||||
while (!fp.eof()) {
|
||||
SpvWord inWord;
|
||||
fp.read((char *)&inWord, sizeof(inWord));
|
||||
|
||||
if (!fp.eof()) {
|
||||
spv.push_back(inWord);
|
||||
if (fp.fail())
|
||||
errHandler(std::string("error reading file: ") + inFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write(std::vector<SpvWord>& spv, const std::string& outFile, int verbosity)
|
||||
{
|
||||
if (outFile.empty())
|
||||
errHandler("missing output filename.");
|
||||
|
||||
std::ofstream fp;
|
||||
|
||||
if (verbosity > 0)
|
||||
logHandler(std::string(" writing: ") + outFile);
|
||||
|
||||
fp.open(outFile, std::fstream::out | std::fstream::binary);
|
||||
|
||||
if (fp.fail())
|
||||
errHandler(std::string("error opening file for write: ") + outFile);
|
||||
|
||||
for (auto it = spv.cbegin(); it != spv.cend(); ++it) {
|
||||
SpvWord word = *it;
|
||||
fp.write((char *)&word, sizeof(word));
|
||||
if (fp.fail())
|
||||
errHandler(std::string("error writing file: ") + outFile);
|
||||
}
|
||||
|
||||
// file is closed by destructor
|
||||
}
|
||||
|
||||
// Print helpful usage message to stdout, and exit
|
||||
void usage(const char* const name, const char* const msg = 0)
|
||||
{
|
||||
if (msg)
|
||||
std::cout << msg << std::endl << std::endl;
|
||||
|
||||
std::cout << "Usage: " << std::endl;
|
||||
|
||||
std::cout << " " << basename(name)
|
||||
<< " [-v[v[...]] | --verbose [int]]"
|
||||
<< " [--map (all|types|names|funcs)]"
|
||||
<< " [--dce (all|types|funcs)]"
|
||||
<< " [--opt (all|loadstore)]"
|
||||
<< " [--strip-all | --strip all | -s]"
|
||||
<< " [--do-everything]"
|
||||
<< " --input | -i file1 [file2...] --output|-o DESTDIR"
|
||||
<< std::endl;
|
||||
|
||||
std::cout << " " << basename(name) << " [--version | -V]" << std::endl;
|
||||
std::cout << " " << basename(name) << " [--help | -?]" << std::endl;
|
||||
|
||||
exit(5);
|
||||
}
|
||||
|
||||
// grind through each SPIR in turn
|
||||
void execute(const std::vector<std::string>& inputFile, const std::string& outputDir,
|
||||
int opts, int verbosity)
|
||||
{
|
||||
for (auto it = inputFile.cbegin(); it != inputFile.cend(); ++it) {
|
||||
const std::string &filename = *it;
|
||||
std::vector<SpvWord> spv;
|
||||
read(spv, filename, verbosity);
|
||||
spv::spirvbin_t(verbosity).remap(spv, opts);
|
||||
|
||||
const std::string outfile = outputDir + path_sep_char() + basename(filename);
|
||||
|
||||
write(spv, outfile, verbosity);
|
||||
}
|
||||
|
||||
if (verbosity > 0)
|
||||
std::cout << "Done: " << inputFile.size() << " file(s) processed" << std::endl;
|
||||
}
|
||||
|
||||
// Parse command line options
|
||||
void parseCmdLine(int argc, char** argv, std::vector<std::string>& inputFile,
|
||||
std::string& outputDir,
|
||||
int& options,
|
||||
int& verbosity)
|
||||
{
|
||||
if (argc < 2)
|
||||
usage(argv[0]);
|
||||
|
||||
verbosity = 0;
|
||||
options = spv::spirvbin_t::NONE;
|
||||
|
||||
// Parse command line.
|
||||
// boost::program_options would be quite a bit nicer, but we don't want to
|
||||
// introduce a dependency on boost.
|
||||
for (int a=1; a<argc; ) {
|
||||
const std::string arg = argv[a];
|
||||
|
||||
if (arg == "--output" || arg == "-o") {
|
||||
// Output directory
|
||||
if (++a >= argc)
|
||||
usage(argv[0], "--output requires an argument");
|
||||
if (!outputDir.empty())
|
||||
usage(argv[0], "--output can be provided only once");
|
||||
|
||||
outputDir = argv[a++];
|
||||
|
||||
// Remove trailing directory separator characters
|
||||
while (!outputDir.empty() && outputDir.back() == path_sep_char())
|
||||
outputDir.pop_back();
|
||||
|
||||
}
|
||||
else if (arg == "-vv") { verbosity = 2; ++a; } // verbosity shortcuts
|
||||
else if (arg == "-vvv") { verbosity = 3; ++a; } // ...
|
||||
else if (arg == "-vvvv") { verbosity = 4; ++a; } // ...
|
||||
else if (arg == "-vvvvv") { verbosity = 5; ++a; } // ...
|
||||
|
||||
else if (arg == "--verbose" || arg == "-v") {
|
||||
++a;
|
||||
verbosity = 1;
|
||||
|
||||
if (a < argc) {
|
||||
char* end_ptr = 0;
|
||||
int verb = ::strtol(argv[a], &end_ptr, 10);
|
||||
// If we have not read to the end of the string or
|
||||
// the string contained no elements, then we do not want to
|
||||
// store the value.
|
||||
if (*end_ptr == '\0' && end_ptr != argv[a]) {
|
||||
verbosity = verb;
|
||||
++a;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (arg == "--version" || arg == "-V") {
|
||||
std::cout << basename(argv[0]) << " version 0.97" << std::endl;
|
||||
exit(0);
|
||||
} else if (arg == "--input" || arg == "-i") {
|
||||
// Collect input files
|
||||
for (++a; a < argc && argv[a][0] != '-'; ++a)
|
||||
inputFile.push_back(argv[a]);
|
||||
} else if (arg == "--do-everything") {
|
||||
++a;
|
||||
options = options | spv::spirvbin_t::DO_EVERYTHING;
|
||||
} else if (arg == "--strip-all" || arg == "-s") {
|
||||
++a;
|
||||
options = options | spv::spirvbin_t::STRIP;
|
||||
} else if (arg == "--strip") {
|
||||
++a;
|
||||
if (strncmp(argv[a], "all", 3) == 0) {
|
||||
options = options | spv::spirvbin_t::STRIP;
|
||||
++a;
|
||||
}
|
||||
} else if (arg == "--dce") {
|
||||
// Parse comma (or colon, etc) separated list of things to dce
|
||||
++a;
|
||||
for (const char* c = argv[a]; *c; ++c) {
|
||||
if (strncmp(c, "all", 3) == 0) {
|
||||
options = (options | spv::spirvbin_t::DCE_ALL);
|
||||
c += 3;
|
||||
} else if (strncmp(c, "*", 1) == 0) {
|
||||
options = (options | spv::spirvbin_t::DCE_ALL);
|
||||
c += 1;
|
||||
} else if (strncmp(c, "funcs", 5) == 0) {
|
||||
options = (options | spv::spirvbin_t::DCE_FUNCS);
|
||||
c += 5;
|
||||
} else if (strncmp(c, "types", 5) == 0) {
|
||||
options = (options | spv::spirvbin_t::DCE_TYPES);
|
||||
c += 5;
|
||||
}
|
||||
}
|
||||
++a;
|
||||
} else if (arg == "--map") {
|
||||
// Parse comma (or colon, etc) separated list of things to map
|
||||
++a;
|
||||
for (const char* c = argv[a]; *c; ++c) {
|
||||
if (strncmp(c, "all", 3) == 0) {
|
||||
options = (options | spv::spirvbin_t::MAP_ALL);
|
||||
c += 3;
|
||||
} else if (strncmp(c, "*", 1) == 0) {
|
||||
options = (options | spv::spirvbin_t::MAP_ALL);
|
||||
c += 1;
|
||||
} else if (strncmp(c, "types", 5) == 0) {
|
||||
options = (options | spv::spirvbin_t::MAP_TYPES);
|
||||
c += 5;
|
||||
} else if (strncmp(c, "names", 5) == 0) {
|
||||
options = (options | spv::spirvbin_t::MAP_NAMES);
|
||||
c += 5;
|
||||
} else if (strncmp(c, "funcs", 5) == 0) {
|
||||
options = (options | spv::spirvbin_t::MAP_FUNCS);
|
||||
c += 5;
|
||||
}
|
||||
}
|
||||
++a;
|
||||
} else if (arg == "--opt") {
|
||||
++a;
|
||||
for (const char* c = argv[a]; *c; ++c) {
|
||||
if (strncmp(c, "all", 3) == 0) {
|
||||
options = (options | spv::spirvbin_t::OPT_ALL);
|
||||
c += 3;
|
||||
} else if (strncmp(c, "*", 1) == 0) {
|
||||
options = (options | spv::spirvbin_t::OPT_ALL);
|
||||
c += 1;
|
||||
} else if (strncmp(c, "loadstore", 9) == 0) {
|
||||
options = (options | spv::spirvbin_t::OPT_LOADSTORE);
|
||||
c += 9;
|
||||
}
|
||||
}
|
||||
++a;
|
||||
} else if (arg == "--help" || arg == "-?") {
|
||||
usage(argv[0]);
|
||||
} else {
|
||||
usage(argv[0], "Unknown command line option");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::vector<std::string> inputFile;
|
||||
std::string outputDir;
|
||||
int opts;
|
||||
int verbosity;
|
||||
|
||||
#ifdef use_cpp11
|
||||
// handle errors by exiting
|
||||
spv::spirvbin_t::registerErrorHandler(errHandler);
|
||||
|
||||
// Log messages to std::cout
|
||||
spv::spirvbin_t::registerLogHandler(logHandler);
|
||||
#endif
|
||||
|
||||
if (argc < 2)
|
||||
usage(argv[0]);
|
||||
|
||||
parseCmdLine(argc, argv, inputFile, outputDir, opts, verbosity);
|
||||
|
||||
if (outputDir.empty())
|
||||
usage(argv[0], "Output directory required");
|
||||
|
||||
// Main operations: read, remap, and write.
|
||||
execute(inputFile, outputDir, opts, verbosity);
|
||||
|
||||
// If we get here, everything went OK! Nothing more to be done.
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
MaxLights 32
|
||||
MaxClipPlanes 6
|
||||
MaxTextureUnits 32
|
||||
MaxTextureCoords 32
|
||||
MaxVertexAttribs 8
|
||||
MaxVertexUniformComponents 4096
|
||||
MaxVaryingFloats 64
|
||||
MaxVertexTextureImageUnits 0
|
||||
MaxCombinedTextureImageUnits 8
|
||||
MaxTextureImageUnits 8
|
||||
MaxFragmentUniformComponents 4096
|
||||
MaxDrawBuffers 1
|
||||
MaxVertexUniformVectors 16
|
||||
MaxVaryingVectors 8
|
||||
MaxFragmentUniformVectors 16
|
||||
MaxVertexOutputVectors 16
|
||||
MaxFragmentInputVectors 15
|
||||
MinProgramTexelOffset -8
|
||||
MaxProgramTexelOffset 7
|
||||
nonInductiveForLoops 0
|
||||
whileLoops 0
|
||||
doWhileLoops 0
|
||||
generalUniformIndexing 0
|
||||
generalAttributeMatrixVectorIndexing 0
|
||||
generalVaryingIndexing 0
|
||||
generalSamplerIndexing 0
|
||||
generalVariableIndexing 0
|
||||
generalConstantMatrixVectorIndexing 0
|
|
@ -1,230 +0,0 @@
|
|||
// okay
|
||||
#version 100
|
||||
int a[3] = { 2, 3, 4, }; // ERROR (lots)
|
||||
#version 100
|
||||
int uint;
|
||||
|
||||
attribute vec4 v[3]; // ERROR
|
||||
|
||||
float f = 2; // ERROR
|
||||
|
||||
uniform block { // ERROR
|
||||
int x;
|
||||
};
|
||||
|
||||
void foo(float);
|
||||
|
||||
void main()
|
||||
{
|
||||
foo(3); // ERROR
|
||||
int s = 1 << 4; // ERROR
|
||||
s = 16 >> 2; // ERROR
|
||||
if (a == a); // ERROR
|
||||
int b, c;
|
||||
b = c & 4; // ERROR
|
||||
b = c % 4; // ERROR
|
||||
b = c | 4; // ERROR
|
||||
b >>= 2; // ERROR
|
||||
b <<= 2; // ERROR
|
||||
b %= 3; // ERROR
|
||||
|
||||
struct S {
|
||||
float f;
|
||||
float a[10];
|
||||
} s1, s2;
|
||||
|
||||
s1 = s2; // ERROR
|
||||
if (s1 == s2); // ERROR
|
||||
if (s1 != s2); // ERROR
|
||||
|
||||
switch(b) { // ERROR
|
||||
}
|
||||
}
|
||||
|
||||
invariant gl_FragColor;
|
||||
float fa[]; // ERROR
|
||||
float f13;
|
||||
invariant f13; // ERROR
|
||||
struct S { int a; };
|
||||
invariant S; // ERROR, not an input or output
|
||||
invariant float fi; // ERROR
|
||||
varying vec4 av;
|
||||
invariant av; // okay in v100
|
||||
|
||||
void foo10()
|
||||
{
|
||||
invariant f; // ERROR
|
||||
invariant float f2; // ERROR
|
||||
float f3;
|
||||
invariant f3; // ERROR
|
||||
}
|
||||
|
||||
uniform vec2 uv2;
|
||||
invariant uv2; // ERROR
|
||||
invariant uniform vec3 uv3; // ERROR
|
||||
|
||||
sampler2D glob2D; // ERROR
|
||||
void f11(sampler2D p2d)
|
||||
{
|
||||
sampler2D v2D; // ERROR
|
||||
}
|
||||
varying sampler2D vary2D; // ERROR
|
||||
|
||||
struct sp {
|
||||
highp float f;
|
||||
in float g; // ERROR
|
||||
uniform float h; // ERROR
|
||||
invariant float i; // ERROR
|
||||
};
|
||||
|
||||
uniform sampler3D s3D; // ERROR
|
||||
|
||||
#extension GL_OES_texture_3D : enable
|
||||
|
||||
precision highp sampler3D;
|
||||
uniform sampler3D s3D2;
|
||||
|
||||
void foo234()
|
||||
{
|
||||
texture3D(s3D2, vec3(0.2), 0.2);
|
||||
texture3DProj(s3D2, v[1], 0.4);
|
||||
dFdx(v[0]); // ERROR
|
||||
dFdy(3.2); // ERROR
|
||||
fwidth(f13); // ERROR
|
||||
}
|
||||
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
|
||||
void foo236()
|
||||
{
|
||||
dFdx(v[0]);
|
||||
dFdy(3.2);
|
||||
fwidth(f13);
|
||||
gl_FragDepth = f13; // ERROR
|
||||
gl_FragDepthEXT = f13; // ERROR
|
||||
}
|
||||
|
||||
#extension GL_EXT_frag_depth : enable
|
||||
|
||||
void foo239()
|
||||
{
|
||||
gl_FragDepth = f13; // ERROR
|
||||
gl_FragDepthEXT = f13;
|
||||
}
|
||||
|
||||
#extension GL_OES_EGL_image_external : enable
|
||||
|
||||
uniform samplerExternalOES sExt;
|
||||
|
||||
void foo245()
|
||||
{
|
||||
texture2D(sExt, vec2(0.2));
|
||||
texture2DProj(sExt, vec3(f13));
|
||||
texture2DProj(sExt, v[2]);
|
||||
}
|
||||
|
||||
precision mediump samplerExternalOES;
|
||||
uniform samplerExternalOES mediumExt;
|
||||
uniform highp samplerExternalOES highExt;
|
||||
|
||||
void foo246()
|
||||
{
|
||||
texture2D(mediumExt, vec2(0.2));
|
||||
texture2DProj(highExt, v[2]);
|
||||
texture3D(sExt, vec3(f13)); // ERROR
|
||||
texture2DProjLod(sExt, vec3(f13), f13); // ERROR
|
||||
int a;
|
||||
~a; // ERROR
|
||||
a | a; // ERROR
|
||||
a & a; // ERROR
|
||||
}
|
||||
|
||||
#extension GL_OES_EGL_image_external : disable
|
||||
uniform sampler2D s2Dg;
|
||||
|
||||
int foo203940(int a, float b, float a) // ERROR, a redefined
|
||||
{
|
||||
texture2DProjGradEXT(s2Dg, vec3(f13), uv2, uv2); // ERROR, extension not enabled
|
||||
return a;
|
||||
}
|
||||
|
||||
float f123 = 4.0f; // ERROR
|
||||
float f124 = 5e10F; // ERROR
|
||||
|
||||
#extension GL_EXT_shader_texture_lod : enable
|
||||
|
||||
uniform samplerCube sCube;
|
||||
|
||||
void foo323433()
|
||||
{
|
||||
texture2DLodEXT(s2Dg, uv2, f13);
|
||||
texture2DProjGradEXT(s2Dg, vec3(f13), uv2, uv2);
|
||||
texture2DGradEXT(s2Dg, uv2, uv2, uv2);
|
||||
textureCubeGradEXT(sCube, vec3(f13), vec3(f13), vec3(f13));
|
||||
}
|
||||
|
||||
int fgfg(float f, mediump int i);
|
||||
int fgfg(float f, highp int i) { return 2; } // ERROR, precision qualifier difference
|
||||
|
||||
int fffg(float f);
|
||||
int fffg(float f); // ERROR, can't have multiple prototypes
|
||||
|
||||
int gggf(float f);
|
||||
int gggf(float f) { return 2; }
|
||||
|
||||
int agggf(float f) { return 2; }
|
||||
int agggf(float f);
|
||||
int agggf(float f); // ERROR, second prototype
|
||||
|
||||
varying struct SSS { float f; } s; // ERROR
|
||||
|
||||
int vf(void);
|
||||
int vf2();
|
||||
int vf3(void v); // ERROR
|
||||
int vf4(int, void); // ERROR
|
||||
int vf5(int, void v); // ERROR
|
||||
|
||||
void badswizzle()
|
||||
{
|
||||
vec3 a[5];
|
||||
a.y; // ERROR, no array swizzle
|
||||
a.zy; // ERROR, no array swizzle
|
||||
a.nothing; // ERROR
|
||||
a.length(); // ERROR, not this version
|
||||
a.method(); // ERROR
|
||||
}
|
||||
|
||||
float fooinit();
|
||||
|
||||
float fooinittest()
|
||||
{
|
||||
return fooinit();
|
||||
}
|
||||
|
||||
// Test extra-function initializers
|
||||
const float fi1 = 3.0;
|
||||
const float fi2 = 4.0;
|
||||
const float fi3 = 5.0;
|
||||
|
||||
float fooinit()
|
||||
{
|
||||
return fi1 + fi2 + fi3; // should make a constant of 12.0
|
||||
}
|
||||
|
||||
int init1 = gl_FrontFacing ? 1 : 2; // ERROR, non-const initializer
|
||||
|
||||
#ifdef GL_EXT_shader_non_constant_global_initializers
|
||||
#extension GL_EXT_shader_non_constant_global_initializers : enable
|
||||
#endif
|
||||
|
||||
int init2 = gl_FrontFacing ? 1 : 2;
|
||||
|
||||
#define A__B // error
|
||||
int a__b; // error
|
||||
|
||||
#pragma STDGL invariant(all)
|
||||
|
||||
#line 3000
|
||||
#error line of this error should be 3000
|
||||
|
||||
uniform samplerExternalOES badExt; // syntax ERROR
|
|
@ -1,76 +0,0 @@
|
|||
#version 100
|
||||
|
||||
int ga, gb;
|
||||
float f;
|
||||
|
||||
uniform sampler2D fsa[3];
|
||||
uniform float fua[10];
|
||||
attribute mat3 am3;
|
||||
attribute vec2 av2;
|
||||
varying vec4 va[4];
|
||||
|
||||
const mat2 m2 = mat2(1.0);
|
||||
const vec3 v3 = vec3(2.0);
|
||||
|
||||
void foo(inout float a) {}
|
||||
|
||||
int bar()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
while (ga < gb) { }
|
||||
|
||||
do { } while (false);
|
||||
|
||||
for ( ; ; ); // ERROR
|
||||
for ( ; ga==gb; ); // ERROR
|
||||
for ( ; ; f++); // ERROR
|
||||
for ( ga = 0; ; ); // ERROR
|
||||
for ( bool a = false; ; ); // ERROR
|
||||
for (float a = 0.0; a == sin(f); ); // ERROR
|
||||
for ( int a = 0; a < 10; a *= 2); // ERROR
|
||||
for ( int a = 0; a <= 20; a++) --a; // ERROR
|
||||
for ( int a = 0; a <= 20; a++) { if (ga==0) a = 4; } // ERROR
|
||||
for (float a = 0.0; a <= 20.0; a += 2.0);
|
||||
for (float a = 0.0; a != 20.0; a -= 2.0) { if (ga==0) ga = 4; }
|
||||
for (float a = 0.0; a == 20.0; a--) for (float a = 0.0; a == 20.0; a--); // two different 'a's, everything okay
|
||||
for (float a = 0.0; a <= 20.0; a += 2.0);
|
||||
for (float a = 0.0; a <= 20.0; a += 2.0);
|
||||
for (float a = 0.0; a > 2.0 * 20.0; a += v3.y);
|
||||
for (float a = 0.0; a >= 20.0; a += 2.0) foo(a); // ERROR
|
||||
|
||||
int ia[9];
|
||||
|
||||
fsa[ga]; // ERROR
|
||||
fua[ga];
|
||||
am3[ga]; // ERROR
|
||||
av2[ga]; // ERROR
|
||||
va[2+ga]; // ERROR
|
||||
m2[ga]; // ERROR
|
||||
v3[ga/2]; // ERROR
|
||||
ia[ga]; // ERROR
|
||||
|
||||
for (int a = 3; a >= 0; a--) {
|
||||
fsa[a];
|
||||
fua[a+2];
|
||||
am3[3*a];
|
||||
av2[3*a];
|
||||
va[a-1];
|
||||
m2[a/2];
|
||||
v3[a];
|
||||
ia[a];
|
||||
ia[bar()]; // ERROR
|
||||
}
|
||||
|
||||
fsa[2];
|
||||
fua[3];
|
||||
am3[2];
|
||||
av2[1];
|
||||
va[1];
|
||||
m2[1];
|
||||
v3[1];
|
||||
ia[3];
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#version 100
|
||||
|
||||
#extension GL_OES_EGL_image_external : enable
|
||||
|
||||
uniform samplerExternalOES sExt;
|
||||
precision mediump samplerExternalOES;
|
||||
uniform samplerExternalOES mediumExt;
|
||||
uniform highp samplerExternalOES highExt;
|
||||
|
||||
void main()
|
||||
{
|
||||
texture2D(sExt, vec2(0.2));
|
||||
texture2D(mediumExt, vec2(0.2));
|
||||
texture2D(highExt, vec2(0.2));
|
||||
texture2DProj(sExt, vec3(0.3));
|
||||
texture2DProj(sExt, vec4(0.3));
|
||||
|
||||
int lod = 0;
|
||||
highp float bias = 0.01;
|
||||
textureSize(sExt, lod); // ERROR
|
||||
texture(sExt, vec2(0.2)); // ERROR
|
||||
texture(sExt, vec2(0.2), bias); // ERROR
|
||||
textureProj(sExt, vec3(0.2)); // ERROR
|
||||
textureProj(sExt, vec3(0.2), bias); // ERROR
|
||||
textureProj(sExt, vec4(0.2)); // ERROR
|
||||
textureProj(sExt, vec4(0.2), bias); // ERROR
|
||||
texelFetch(sExt, ivec2(4), lod); // ERROR
|
||||
|
||||
texture3D(sExt, vec3(0.3)); // ERROR
|
||||
texture2DProjLod(sExt, vec3(0.3), 0.3); // ERROR
|
||||
texture(sExt, vec3(0.3)); // ERROR
|
||||
textureProjLod(sExt, vec3(0.3), 0.3); // ERROR
|
||||
}
|
||||
|
||||
#extension GL_OES_EGL_image_external : disable
|
||||
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
uniform samplerExternalOES badExt; // ERROR
|
||||
#extension GL_OES_EGL_image_external_essl3 : disable
|
||||
|
||||
uniform samplerExternalOES badExt; // ERROR
|
|
@ -1,76 +0,0 @@
|
|||
#version 100
|
||||
|
||||
int f(int a, int b, int c)
|
||||
{
|
||||
int a = b; // ERROR, redefinition
|
||||
|
||||
{
|
||||
float a = float(a) + 1.0;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int f(int a, int b, int c); // okay to redeclare
|
||||
|
||||
bool b;
|
||||
float b(int a); // ERROR: redefinition
|
||||
|
||||
float c(int a);
|
||||
bool c; // ERROR: redefinition
|
||||
|
||||
float f; // ERROR: redefinition
|
||||
float tan; // okay, built-in is in an outer scope
|
||||
float sin(float x); // ERROR: can't redefine built-in functions
|
||||
float cos(float x) // ERROR: can't redefine built-in functions
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
bool radians(bool x) // okay, can overload built-in functions
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
invariant gl_Position;
|
||||
|
||||
void main()
|
||||
{
|
||||
int g(); // ERROR: no local function declarations
|
||||
g();
|
||||
|
||||
float sin; // okay
|
||||
sin;
|
||||
sin(0.7); // ERROR, use of hidden function
|
||||
f(1,2,3);
|
||||
|
||||
float f; // hides f()
|
||||
f = 3.0;
|
||||
|
||||
gl_Position = vec4(f);
|
||||
|
||||
for (int f = 0; f < 10; ++f)
|
||||
++f;
|
||||
|
||||
int x = 1;
|
||||
{
|
||||
float x = 2.0, /* 2nd x visible here */ y = x; // y is initialized to 2
|
||||
int z = z; // ERROR: z not previously defined.
|
||||
}
|
||||
{
|
||||
int x = x; // x is initialized to '1'
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int x;
|
||||
};
|
||||
{
|
||||
S S = S(0); // 'S' is only visible as a struct and constructor
|
||||
S.x; // 'S' is now visible as a variable
|
||||
}
|
||||
|
||||
int degrees;
|
||||
degrees(3.2); // ERROR, use of hidden built-in function
|
||||
}
|
||||
|
||||
varying struct SSS { float f; } s; // ERROR
|
|
@ -1,87 +0,0 @@
|
|||
#version 110
|
||||
|
||||
int f(int a, int b, int c)
|
||||
{
|
||||
int a = b; // ERROR, redefinition
|
||||
|
||||
{
|
||||
float a = float(a) + 1.0; // okay
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int f(int a, int b, int c); // okay to redeclare
|
||||
|
||||
bool b;
|
||||
float b(int a); // okay, b and b() are different
|
||||
|
||||
float c(int a);
|
||||
bool c; // okay, and c() are different
|
||||
|
||||
float f; // okay f and f() are different
|
||||
float tan; // okay, hides built-in function
|
||||
float sin(float x); // okay, can redefine built-in functions
|
||||
float cos(float x) // okay, can redefine built-in functions
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
bool radians(bool x) // okay, can overload built-in functions
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int gi = f(1,2,3); // ERROR, can't call user-defined function from global scope
|
||||
|
||||
void main()
|
||||
{
|
||||
int g(); // okay
|
||||
g();
|
||||
|
||||
float sin; // okay
|
||||
sin;
|
||||
sin(0.7); // okay
|
||||
f(1,2,3);
|
||||
|
||||
float f;
|
||||
f = 3.0;
|
||||
|
||||
gl_Position = vec4(f);
|
||||
|
||||
for (int f = 0; f < 10; ++f)
|
||||
++f;
|
||||
|
||||
int x = 1;
|
||||
{
|
||||
float x = 2.0, /* 2nd x visible here */ y = x; // y is initialized to 2
|
||||
int z = z; // ERROR: z not previously defined.
|
||||
}
|
||||
{
|
||||
int x = x; // x is initialized to '1'
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int x;
|
||||
};
|
||||
{
|
||||
S S = S(0); // 'S' is only visible as a struct and constructor
|
||||
S.x; // 'S' is now visible as a variable
|
||||
}
|
||||
|
||||
int degrees;
|
||||
degrees(3.2);
|
||||
|
||||
{
|
||||
S s;
|
||||
s.x = 3;
|
||||
struct S { // okay, hides S
|
||||
bool b;
|
||||
};
|
||||
S t;
|
||||
t.b = true;
|
||||
struct S { // ERROR, redefinition of struct S
|
||||
float f;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
#version 120
|
||||
|
||||
float lowp;
|
||||
float mediump;
|
||||
float highp;
|
||||
|
||||
float precision;
|
||||
|
||||
in vec4 i;
|
||||
out vec4 o;
|
||||
|
||||
uniform sampler2D s2D;
|
||||
centroid varying vec2 centTexCoord;
|
||||
|
||||
uniform mat4x2 m;
|
||||
|
||||
struct s {
|
||||
float f;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
mat2x3 m23 = mat2x3(m);
|
||||
|
||||
int a;
|
||||
bool b;
|
||||
s sv = s(a);
|
||||
float[2] ia = float[2](3, i.y);
|
||||
float f1 = 1;
|
||||
float f = a;
|
||||
f = a;
|
||||
ivec3 iv3;
|
||||
vec3 v3 = iv3;
|
||||
f = f + a;
|
||||
f = a - f;
|
||||
f += a;
|
||||
f = a - f;
|
||||
v3 *= iv3;
|
||||
v3 = iv3 / 2.0f;
|
||||
v3 = 3.0 * iv3;
|
||||
v3 = 2 * v3;
|
||||
v3 = v3 - 2;
|
||||
if (f < a ||
|
||||
a <= f ||
|
||||
f > a ||
|
||||
f >= a ||
|
||||
a == f ||
|
||||
f != a);
|
||||
f = b ? a : f;
|
||||
f = b ? f : a;
|
||||
f = b ? a : a;
|
||||
s news = sv;
|
||||
|
||||
i.xy + i.xyz; // ERROR
|
||||
m * i.xyz; // ERROR
|
||||
m + i; // ERROR
|
||||
int aoeu = 1.0; // ERROR
|
||||
f = b; // ERROR
|
||||
f = a + b; // ERROR
|
||||
f = b * a; // ERROR
|
||||
b = a; // ERROR
|
||||
b = b + f; // ERROR
|
||||
f |= b; // ERROR
|
||||
|
||||
gl_FragColor = texture2D(s2D, centTexCoord);
|
||||
|
||||
float flat;
|
||||
float smooth;
|
||||
float noperspective;
|
||||
float uvec2;
|
||||
float uvec3;
|
||||
float uvec4;
|
||||
//packed; // ERROR, reserved word
|
||||
|
||||
{
|
||||
mat4 m;
|
||||
vec4 v;
|
||||
bool b;
|
||||
gl_FragColor += b ? v : m; // ERROR, types don't match around ":"
|
||||
}
|
||||
|
||||
gl_FragColor.xr; // ERROR, swizzlers not from same field space
|
||||
gl_FragColor.xyxyx.xy; // ERROR, cannot make a vec5, even temporarily
|
||||
centTexCoord.z; // ERROR, swizzler out of range
|
||||
(a,b) = true; // ERROR, not an l-value
|
||||
}
|
||||
|
||||
float imageBuffer;
|
||||
float uimage2DRect;
|
||||
|
||||
int main() {} // ERROR
|
||||
void main(int a) {} // ERROR
|
||||
|
||||
const int a; // ERROR
|
||||
|
||||
int foo(in float a);
|
||||
int foo(out float a) // ERROR
|
||||
{
|
||||
return 3.2; // ERROR
|
||||
foo(a); // ERROR
|
||||
}
|
||||
|
||||
bool gen(vec3 v)
|
||||
{
|
||||
if (abs(v[0]) < 1e-4F && abs(v[1]) < 1e-4)
|
||||
return true;
|
||||
}
|
||||
|
||||
void v1()
|
||||
{
|
||||
}
|
||||
|
||||
void v2()
|
||||
{
|
||||
return v1(); // ERROR, no expression allowed, even though void
|
||||
}
|
||||
|
||||
void atest()
|
||||
{
|
||||
vec4 v = gl_TexCoord[1];
|
||||
v += gl_TexCoord[3];
|
||||
}
|
||||
|
||||
varying vec4 gl_TexCoord[6]; // okay, assigning a size
|
||||
varying vec4 gl_TexCoord[5]; // ERROR, changing size
|
||||
|
||||
mat2x2 m22;
|
||||
mat2x3 m23;
|
||||
mat2x4 m24;
|
||||
|
||||
mat3x2 m32;
|
||||
mat3x3 m33;
|
||||
mat3x4 m34;
|
||||
|
||||
mat4x2 m42;
|
||||
mat4x3 m43;
|
||||
mat4x4 m44;
|
||||
|
||||
void foo123()
|
||||
{
|
||||
mat2 r2 = matrixCompMult(m22, m22);
|
||||
mat3 r3 = matrixCompMult(m33, m33);
|
||||
mat4 r4 = matrixCompMult(m44, m44);
|
||||
|
||||
mat2x3 r23 = matrixCompMult(m23, m23);
|
||||
mat2x4 r24 = matrixCompMult(m24, m24);
|
||||
mat3x2 r32 = matrixCompMult(m32, m32);
|
||||
mat3x4 r34 = matrixCompMult(m34, m34);
|
||||
mat4x2 r42 = matrixCompMult(m42, m42);
|
||||
mat4x3 r43 = matrixCompMult(m43, m43);
|
||||
|
||||
mat3x2 rfoo1 = matrixCompMult(m23, m32); // ERROR
|
||||
mat3x4 rfoo2 = matrixCompMult(m34, m44); // ERROR
|
||||
}
|
||||
|
||||
void matConst()
|
||||
{
|
||||
vec2 v2;
|
||||
vec3 v3;
|
||||
mat4 m4b1 = mat4(v2, v3); // ERROR, not enough
|
||||
mat4 m4b2 = mat4(v2, v3, v3, v3, v3, v2, v2); // ERROR, too much
|
||||
mat4 m4g = mat4(v2, v3, v3, v3, v3, v3);
|
||||
mat4 m4 = mat4(v2, v3, v3, v3, v3, v2);
|
||||
mat3 m3 = mat3(m4);
|
||||
mat3 m3b1 = mat3(m4, v2); // ERROR, extra arg
|
||||
mat3 m3b2 = mat3(m4, m4); // ERROR, extra arg
|
||||
mat3x2 m32 = mat3x2(m4);
|
||||
mat4 m4c = mat4(m32);
|
||||
mat3 m3s = mat3(v2.x);
|
||||
|
||||
mat3 m3a1[2] = mat3[2](m3s, m3s);
|
||||
mat3 m3a2[2] = mat3[2](m3s, m3s, m3s); // ERROR, too many args
|
||||
}
|
||||
|
||||
uniform sampler3D s3D;
|
||||
uniform sampler1D s1D;
|
||||
uniform sampler2DShadow s2DS;
|
||||
|
||||
void foo2323()
|
||||
{
|
||||
vec4 v;
|
||||
vec2 v2;
|
||||
float f;
|
||||
v = texture2DLod(s2D, v2, f); // ERROR
|
||||
v = texture3DProjLod(s3D, v, f); // ERROR
|
||||
v = texture1DProjLod(s1D, v, f); // ERROR
|
||||
v = shadow2DProjLod(s2DS, v, f); // ERROR
|
||||
|
||||
v = texture1DGradARB(s1D, f, f, f); // ERROR
|
||||
v = texture2DProjGradARB(s2D, v, v2, v2); // ERROR
|
||||
v = shadow2DProjGradARB(s2DS, v, v2, v2); // ERROR
|
||||
}
|
||||
|
||||
#extension GL_ARB_shader_texture_lod : require
|
||||
|
||||
void foo2324()
|
||||
{
|
||||
vec4 v;
|
||||
vec2 v2;
|
||||
float f;
|
||||
v = texture2DLod(s2D, v2, f);
|
||||
v = texture3DProjLod(s3D, v, f);
|
||||
v = texture1DProjLod(s1D, v, f);
|
||||
v = shadow2DProjLod(s2DS, v, f);
|
||||
|
||||
v = texture1DGradARB(s1D, f, f, f);
|
||||
v = texture2DProjGradARB(s2D, v, v2, v2);
|
||||
v = shadow2DProjGradARB(s2DS, v, v2, v2);
|
||||
v = shadow2DRectProjGradARB(s2DS, v, v2, v2); // ERROR
|
||||
}
|
||||
|
||||
uniform sampler2DRect s2DRbad; // ERROR
|
||||
|
||||
void foo121111()
|
||||
{
|
||||
vec2 v2;
|
||||
vec4 v = texture2DRect(s2DRbad, v2);
|
||||
}
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
uniform sampler2DRect s2DR;
|
||||
uniform sampler2DRectShadow s2DRS;
|
||||
|
||||
void foo12111()
|
||||
{
|
||||
vec2 v2;
|
||||
vec3 v3;
|
||||
vec4 v4;
|
||||
vec4 v;
|
||||
v = texture2DRect(s2DR, v2);
|
||||
v = texture2DRectProj(s2DR, v3);
|
||||
v = texture2DRectProj(s2DR, v4);
|
||||
v = shadow2DRect(s2DRS, v3);
|
||||
v = shadow2DRectProj(s2DRS, v4);
|
||||
|
||||
v = shadow2DRectProjGradARB(s2DRS, v, v2, v2);
|
||||
}
|
||||
|
||||
void voidTernary()
|
||||
{
|
||||
bool b;
|
||||
b ? foo121111() : foo12111();
|
||||
b ? foo121111() : 4; // ERROR
|
||||
b ? 3 : foo12111(); // ERROR
|
||||
}
|
||||
|
||||
float halfFloat1 = 1.0h; // syntax ERROR
|
|
@ -1,215 +0,0 @@
|
|||
#version 120
|
||||
|
||||
in vec4 i; // ERROR
|
||||
out vec4 o; // ERROR
|
||||
|
||||
attribute vec2 attv2;
|
||||
attribute vec4 attv4;
|
||||
uniform sampler2D s2D;
|
||||
invariant varying vec2 centTexCoord;
|
||||
invariant gl_Position;
|
||||
centroid gl_Position; // ERROR
|
||||
centroid centroid foo; // ERROR
|
||||
invariant gl_Position, gl_PointSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
centTexCoord = attv2;
|
||||
gl_Position = attv4;
|
||||
|
||||
gl_ClipVertex = attv4;
|
||||
gl_ClipDistance[1] = 0.2; // ERROR
|
||||
|
||||
vec3[12] a;
|
||||
vec4[a.length()] b;
|
||||
gl_Position = b[b.length()-1];
|
||||
|
||||
float f[];
|
||||
int a1 = f.length(); // ERROR
|
||||
float f[7];
|
||||
int aa = f.length();
|
||||
int a2 = f.length; // ERROR
|
||||
int a3 = f.length(a); // ERROR
|
||||
int a4 = f.flizbit; // ERROR
|
||||
int a4 = f.flizbit(); // ERROR
|
||||
float md[2][4]; // ERROR
|
||||
float[2] md2[4]; // ERROR
|
||||
float[2][4] md3; // ERROR
|
||||
float md5, md6[2][3]; // ERROR
|
||||
float[2] md4, md7[4]; // ERROR
|
||||
float md9[2][3] = float[2][3](1, 2, 3, 4, 5, 6); // ERROR
|
||||
float md10, md11[2][3] = float[2][3](1, 2, 3, 4, 5, 6); // ERROR
|
||||
|
||||
gl_PointSize = 3.8;
|
||||
}
|
||||
|
||||
uniform float initted = 3.4; // okay
|
||||
|
||||
const float concall = sin(0.3);
|
||||
|
||||
int[2][3] foo( // ERROR
|
||||
float[2][3] a, // ERROR
|
||||
float[2] b[3], // ERROR
|
||||
float c[2][3]); // ERROR
|
||||
|
||||
int overloadA(in float f);
|
||||
int overloadA(out float f); // ERROR, different qualifiers
|
||||
float overloadA(float); // ERROR, different return value for same signature
|
||||
float overloadA(out float f, int);
|
||||
float overloadA(int i);
|
||||
|
||||
void overloadB(float, const in float) { }
|
||||
|
||||
vec2 overloadC(int, int);
|
||||
vec2 overloadC(const in int, float);
|
||||
vec2 overloadC(float, int);
|
||||
vec2 overloadC(vec2, vec2);
|
||||
|
||||
vec3 overloadD(int, float);
|
||||
vec3 overloadD(float, in int);
|
||||
|
||||
vec3 overloadE(float[2]);
|
||||
vec3 overloadE(mat2 m);
|
||||
vec3 overloadE(vec2 v);
|
||||
|
||||
vec3 overloadF(int);
|
||||
vec3 overloadF(float);
|
||||
|
||||
void foo()
|
||||
{
|
||||
float f;
|
||||
int i;
|
||||
|
||||
overloadB(f, f);
|
||||
overloadB(f, 2);
|
||||
overloadB(1, i);
|
||||
|
||||
overloadC(1); // ERROR
|
||||
overloadC(1, i);
|
||||
overloadC(vec2(1), vec2(2));
|
||||
overloadC(f, 3.0); // ERROR, no way
|
||||
overloadC(ivec2(1), vec2(2));
|
||||
|
||||
overloadD(i, f);
|
||||
overloadD(f, i);
|
||||
overloadD(i, i); // ERROR, ambiguous
|
||||
|
||||
int overloadB; // hiding
|
||||
overloadB(1, i); // ERROR
|
||||
|
||||
sin(1);
|
||||
texture2D(s2D, ivec2(0));
|
||||
clamp(attv4, 0, 1);
|
||||
clamp(ivec4(attv4), 0, 1);
|
||||
|
||||
int a[2];
|
||||
overloadC(a, 3); // ERROR
|
||||
overloadE(a); // ERROR
|
||||
overloadE(3.3); // ERROR
|
||||
overloadE(vec2(3.3));
|
||||
overloadE(mat2(0.5));
|
||||
overloadE(ivec4(1)); // ERROR
|
||||
overloadE(ivec2(1));
|
||||
|
||||
float b[2];
|
||||
overloadE(b);
|
||||
|
||||
overloadF(1, 1); // ERROR
|
||||
overloadF(1);
|
||||
}
|
||||
|
||||
varying vec4 gl_TexCoord[35]; // ERROR, size too big
|
||||
|
||||
// tests for output conversions
|
||||
void outFun(in float, out ivec2, in int, out float);
|
||||
int outFunRet(in float, out int, const in int, out ivec4);
|
||||
ivec2 outFunRet(in float, out ivec4, in int, out ivec4);
|
||||
|
||||
void foo2()
|
||||
{
|
||||
vec2 v2;
|
||||
vec4 v4;
|
||||
float f;
|
||||
int i;
|
||||
|
||||
outFun(i, v2, i, f);
|
||||
outFunRet(i, f, i, v4);
|
||||
float ret = outFunRet(i, f, i, v4);
|
||||
vec2 ret2 = outFunRet(i, v4, i, v4);
|
||||
bool b = any(lessThan(v4, attv4)); // tests aggregate arg to unary built-in
|
||||
}
|
||||
|
||||
void noise()
|
||||
{
|
||||
float f1 = noise1(1.0);
|
||||
vec2 f2 = noise2(vec2(1.0));
|
||||
vec3 f3 = noise3(vec3(1.0));
|
||||
vec4 f4 = noise4(vec4(1.0));
|
||||
}
|
||||
|
||||
// version 130 features
|
||||
|
||||
uniform int c;
|
||||
|
||||
attribute ivec2 x;
|
||||
attribute vec2 v2a;
|
||||
attribute float c1D;
|
||||
attribute vec2 c2D;
|
||||
attribute vec3 c3D;
|
||||
|
||||
uniform vec4 v4;
|
||||
|
||||
void foo213()
|
||||
{
|
||||
float f = 3;
|
||||
switch (c) { // ERRORs...
|
||||
case 1:
|
||||
f = sin(f);
|
||||
break;
|
||||
case 2:
|
||||
f = f * f;
|
||||
default:
|
||||
f = 3.0;
|
||||
}
|
||||
|
||||
int i;
|
||||
i << 3 | 0x8A >> 1 & 0xFF; // ERRORs...
|
||||
|
||||
vec3 modfOut, modfIn;
|
||||
vec3 v11 = modf(modfIn, modfOut); // ERRORS...
|
||||
float t = trunc(f);
|
||||
vec2 v12 = round(v2a);
|
||||
vec2 v13 = roundEven(v2a);
|
||||
bvec2 b10 = isnan(v2a);
|
||||
bvec4 b11 = isinf(v4);
|
||||
|
||||
sinh(c1D) + // ERRORS...
|
||||
cosh(c1D) * tanh(c2D);
|
||||
asinh(c4D) + acosh(c4D);
|
||||
atanh(c3D);
|
||||
|
||||
int id = gl_VertexID; // ERROR
|
||||
gl_ClipDistance[1] = 0.3; // ERROR
|
||||
}
|
||||
|
||||
int gl_ModelViewMatrix[] = 0;
|
||||
|
||||
// token pasting (ERRORS...)
|
||||
|
||||
#define mac abc##def
|
||||
int mac;
|
||||
|
||||
#define macr(A,B) A ## B
|
||||
int macr(qrs,tuv);
|
||||
|
||||
layout(std140) uniform BlockName // ERROR
|
||||
{
|
||||
int test;
|
||||
};
|
||||
|
||||
#extension GL_ARB_uniform_buffer_object : enable
|
||||
|
||||
layout(std140) uniform BlockName
|
||||
{
|
||||
int test;
|
||||
};
|
|
@ -1,181 +0,0 @@
|
|||
#version 130
|
||||
|
||||
lowp vec3 a;
|
||||
mediump float b;
|
||||
highp int c;
|
||||
|
||||
precision highp float;
|
||||
|
||||
in vec4 i;
|
||||
out vec4 o;
|
||||
|
||||
flat in float fflat;
|
||||
smooth in float fsmooth;
|
||||
noperspective in float fnop;
|
||||
|
||||
void main()
|
||||
{
|
||||
float clip = gl_ClipDistance[3];
|
||||
}
|
||||
|
||||
uniform samplerCube sampC;
|
||||
|
||||
void foo()
|
||||
{
|
||||
vec4 s = textureGather(sampC, vec3(0.2));
|
||||
}
|
||||
|
||||
#extension GL_ARB_texture_gather : enable
|
||||
|
||||
void bar()
|
||||
{
|
||||
vec4 s = textureGather(sampC, vec3(0.2));
|
||||
}
|
||||
|
||||
flat in vec3 gl_Color; // ERROR, type
|
||||
in vec4 gl_Color;
|
||||
flat in vec4 gl_Color;
|
||||
flat in vec4 gl_Color[2]; // ERROR, array
|
||||
vec4 gl_Color; // ERROR, storage
|
||||
|
||||
#extension GL_ARB_texture_gather : warn
|
||||
|
||||
void bar2()
|
||||
{
|
||||
vec4 s = textureGather(sampC, vec3(0.2));
|
||||
|
||||
uvec3 uv3;
|
||||
bvec3 b3;
|
||||
b3 = lessThan(uv3, uv3);
|
||||
b3 = equal(uv3, uv3);
|
||||
const bvec2 bl1 = greaterThanEqual(uvec2(2, 3), uvec2(3,3));
|
||||
const bvec2 bl2 = equal(uvec2(2, 3), uvec2(3,3));
|
||||
const bvec2 bl3 = equal(bl1, bl2); // yes, equal
|
||||
int a1[int(bl3.x)];
|
||||
int a2[int(bl3.y)];
|
||||
a1[0]; // size 1
|
||||
a2[0]; // size 1
|
||||
const bvec4 bl4 = notEqual(greaterThan(uvec4(1,2,3,4), uvec4(0,2,0,6)), lessThanEqual(uvec4(7,8,9,10), uvec4(6, 8, 0, 11))); // compare (t,f,t,f) with (f,t,f,t)
|
||||
int a3[int(bl4.x)+int(bl4.y)+int(bl4.z)+int(bl4.w)];
|
||||
a3[3]; // size 4
|
||||
b3 != b3;
|
||||
b3 < b3; // ERROR
|
||||
uv3 > uv3; // ERROR
|
||||
uvec2(2, 3) >= uvec2(3,3); // ERROR
|
||||
int samples = gl_NumSamples; // ERROR
|
||||
int(bl4) <= int(bl4); // true
|
||||
int(bl4.x) > int(bl4.y); // false
|
||||
}
|
||||
|
||||
#extension GL_ARB_texture_gather : enable
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
#extension GL_ARB_sample_shading : enable
|
||||
|
||||
uniform sampler2D samp2D;
|
||||
uniform sampler2DShadow samp2DS;
|
||||
uniform sampler2DRect samp2DR;
|
||||
uniform sampler2DArray samp2DA;
|
||||
|
||||
void bar23()
|
||||
{
|
||||
vec4 s;
|
||||
s = textureGatherOffset(sampC, vec3(0.3), ivec2(1)); // ERROR
|
||||
s = textureGatherOffset(samp2DR, vec2(0.3), ivec2(1)); // ERROR
|
||||
s = textureGatherOffset(samp2D, vec2(0.3), ivec2(1));
|
||||
s = textureGatherOffset(samp2DA, vec3(0.3), ivec2(1));
|
||||
s = textureGatherOffset(samp2DS, vec2(0.3), 1.3, ivec2(1)); // ERROR
|
||||
s = textureGatherOffset(samp2D, vec2(0.3), ivec2(1), 2); // ERROR
|
||||
int samples = gl_NumSamples;
|
||||
}
|
||||
|
||||
#extension GL_ARB_gpu_shader5 : enable
|
||||
|
||||
void bar234()
|
||||
{
|
||||
vec4 s;
|
||||
s = textureGatherOffset(samp2D, vec2(0.3), ivec2(1));
|
||||
s = textureGatherOffset(samp2DA, vec3(0.3), ivec2(1));
|
||||
s = textureGatherOffset(samp2DR, vec2(0.3), ivec2(1));
|
||||
s = textureGatherOffset(samp2DS, vec2(0.3), 1.3, ivec2(1));
|
||||
s = textureGatherOffset(samp2D, vec2(0.3), ivec2(1), 2);
|
||||
}
|
||||
|
||||
#extension GL_ARB_texture_cube_map_array : enable
|
||||
|
||||
uniform samplerCubeArray Sca;
|
||||
uniform isamplerCubeArray Isca;
|
||||
uniform usamplerCubeArray Usca;
|
||||
uniform samplerCubeArrayShadow Scas;
|
||||
|
||||
void bar235()
|
||||
{
|
||||
ivec3 a = textureSize(Sca, 3);
|
||||
vec4 b = texture(Sca, i);
|
||||
ivec4 c = texture(Isca, i, 0.7);
|
||||
uvec4 d = texture(Usca, i);
|
||||
|
||||
b = textureLod(Sca, i, 1.7);
|
||||
a = textureSize(Scas, a.x);
|
||||
float f = texture(Scas, i, b.y);
|
||||
c = textureGrad(Isca, i, vec3(0.1), vec3(0.2));
|
||||
}
|
||||
|
||||
int \
|
||||
x; // ERROR until 420pack is turned on
|
||||
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
const int ai[3] = { 10, 23, 32 };
|
||||
layout(binding=0) uniform blockname { int a; } instanceName; // ERROR
|
||||
uniform layout(binding=0) sampler2D bounds;
|
||||
|
||||
void bar23444()
|
||||
{
|
||||
mat4x3 m43; \
|
||||
float a1 = m43[3].y;
|
||||
vec3 v3;
|
||||
int a2 = m43.length();
|
||||
a2 += m43[1].length();
|
||||
a2 += v3.length();
|
||||
const float b = 2 * a1;
|
||||
a.x = gl_MinProgramTexelOffset + gl_MaxProgramTexelOffset;
|
||||
bool boolb;
|
||||
boolb.length(); // ERROR
|
||||
m43[3][1].length(); // ERROR
|
||||
v3.length; // ERROR
|
||||
v3.length(b); // ERROR
|
||||
}
|
||||
|
||||
in float gl_FogFragCoord;
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
in float gl_FogFragCoord;
|
||||
in int gl_FogFragCoord; // ERROR
|
||||
|
||||
layout(early_fragment_tests) in; // ERROR
|
||||
layout(r32i) uniform iimage2D iimg2Dbad; // ERROR
|
||||
|
||||
#extension GL_ARB_shader_image_load_store : enable
|
||||
|
||||
layout(early_fragment_tests) in;
|
||||
|
||||
layout(r32i) uniform iimage2D iimg2D;
|
||||
|
||||
void qux2()
|
||||
{
|
||||
int i;
|
||||
imageAtomicCompSwap(iimg2D, ivec2(i,i), i, i);
|
||||
ivec4 pos = imageLoad(iimg2D, ivec2(i,i));
|
||||
}
|
||||
|
||||
layout(early_fragment_tests) out; // ERROR
|
||||
|
||||
#extension GL_ARB_explicit_uniform_location : enable
|
||||
|
||||
layout(location = 3) uniform vec4 ucolor0; // ERROR: explicit attrib location is also required for version < 330
|
||||
|
||||
#extension GL_ARB_explicit_attrib_location : enable
|
||||
|
||||
layout(location = 4) uniform vec4 ucolor1;
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
#version 130
|
||||
|
||||
uniform int c;
|
||||
uniform usampler2D us2D;
|
||||
|
||||
in ivec2 x;
|
||||
in vec2 v2a;
|
||||
in float c1D;
|
||||
in vec2 c2D;
|
||||
in vec3 c3D;
|
||||
smooth vec4 c4D; // ??
|
||||
|
||||
uniform vec4 v4;
|
||||
|
||||
void main()
|
||||
{
|
||||
float f = 3;
|
||||
switch (c) { // full switch testing in switch.frag
|
||||
case 1:
|
||||
f = sin(f);
|
||||
break;
|
||||
case 2:
|
||||
f = f * f;
|
||||
default:
|
||||
f = 3.0;
|
||||
}
|
||||
|
||||
uint i;
|
||||
i = texture(us2D, x).w; // full uint testing in uint.frag
|
||||
i << 3u | 0x8Au >> 1u & 0xFFu;
|
||||
|
||||
vec3 modfOut, modfIn;
|
||||
vec3 v11 = modf(modfIn, modfOut);
|
||||
float t = trunc(f);
|
||||
vec2 v12 = round(v2a);
|
||||
vec2 v13 = roundEven(v2a);
|
||||
bvec2 b10 = isnan(v2a);
|
||||
bvec4 b11 = isinf(v4);
|
||||
|
||||
sinh(c1D) +
|
||||
cosh(c1D) * tanh(c2D);
|
||||
asinh(c4D) + acosh(c4D);
|
||||
atanh(c3D);
|
||||
|
||||
int id = gl_VertexID;
|
||||
gl_ClipDistance[1] = 0.3;
|
||||
}
|
||||
|
||||
// version 140 features
|
||||
|
||||
//uniform isamplerBuffer sbuf;
|
||||
|
||||
//layout(std140) uniform blockName {
|
||||
// int anonMem;
|
||||
//};
|
||||
|
||||
void foo88()
|
||||
{
|
||||
int id = gl_InstanceID; // ERROR
|
||||
//id += anonMem;
|
||||
id += texelFetch(id, 8);
|
||||
|
||||
gl_ClipVertex; // these are all present...
|
||||
gl_Color;
|
||||
gl_LightSource[0];
|
||||
gl_DepthRange.far;
|
||||
gl_TexCoord;
|
||||
gl_FogFragCoord;
|
||||
gl_FrontColor;
|
||||
}
|
||||
|
||||
// token pasting
|
||||
|
||||
#define mac abc##def
|
||||
int mac;
|
||||
|
||||
#define macr(A,B) A##B
|
||||
int macr(qrs,tuv);
|
|
@ -1,60 +0,0 @@
|
|||
#version 140
|
||||
|
||||
varying vec4 v;
|
||||
|
||||
in vec4 i;
|
||||
out vec4 o;
|
||||
|
||||
in float gl_ClipDistance[5];
|
||||
|
||||
void main()
|
||||
{
|
||||
float clip = gl_ClipDistance[2];
|
||||
}
|
||||
#ifdef GL_ES
|
||||
#error GL_ES is set
|
||||
#else
|
||||
#error GL_ES is not set
|
||||
#endif
|
||||
|
||||
|
||||
in struct S { float f; } s; // ERROR
|
||||
|
||||
float patch = 3.1;
|
||||
|
||||
layout(location=3) in vec4 vl; // ERROR
|
||||
|
||||
layout(location = 3) out vec4 factorBad; // ERROR
|
||||
|
||||
#extension GL_ARB_explicit_attrib_location : enable
|
||||
|
||||
layout(location = 5) out vec4 factor;
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(location=4) in vec4 vl2;
|
||||
|
||||
float fooi();
|
||||
|
||||
void foo()
|
||||
{
|
||||
vec2 r1 = modf(v.xy, v.zw); // ERROR, v.zw not l-value
|
||||
vec2 r2 = modf(o.xy, o.zw);
|
||||
o.z = fooi();
|
||||
}
|
||||
|
||||
// Test extra-function initializers
|
||||
|
||||
float i1 = gl_FrontFacing ? -2.0 : 2.0;
|
||||
float i2 = 102;
|
||||
|
||||
float fooi()
|
||||
{
|
||||
return i1 + i2;
|
||||
}
|
||||
|
||||
uniform sampler2DMS aaa1; // ERROR
|
||||
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
uniform sampler2DMS aaa2;
|
|
@ -1,79 +0,0 @@
|
|||
#version 140
|
||||
|
||||
uniform isamplerBuffer sbuf;
|
||||
|
||||
layout(std140) uniform blockName {
|
||||
int anonMem;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
int id = gl_InstanceID;
|
||||
id += anonMem;
|
||||
id += texelFetch(sbuf, 8).w;
|
||||
gl_ClipVertex; // could be ERROR, but compiling under compatibility profile
|
||||
gl_Color; // could be ERROR, but compiling under compatibility profile
|
||||
gl_LightSource[0]; // could be ERROR, but compiling under compatibility profile
|
||||
gl_DepthRange.far;
|
||||
gl_TexCoord; // could be ERROR, but compiling under compatibility profile
|
||||
gl_FogFragCoord; // could be ERROR, but compiling under compatibility profile
|
||||
gl_FrontColor; // could be ERROR, but compiling under compatibility profile
|
||||
}
|
||||
|
||||
out vec4 gl_Position; // ERROR
|
||||
|
||||
layout(location = 9) in vec4 locBad; // ERROR
|
||||
|
||||
#extension GL_ARB_explicit_attrib_location : enable
|
||||
|
||||
layout(location = 9) in vec4 loc;
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
out vec4 gl_Position;
|
||||
in vec4 gl_Position; // ERROR
|
||||
out vec3 gl_Position; // ERROR
|
||||
|
||||
out float gl_PointSize;
|
||||
out vec4 gl_ClipVertex;
|
||||
out float gl_FogFragCoord;
|
||||
|
||||
uniform sampler2DRect s2dr;
|
||||
uniform sampler2DRectShadow s2drs;
|
||||
in ivec2 itloc2;
|
||||
in vec2 tloc2;
|
||||
in vec3 tloc3;
|
||||
in vec4 tloc4;
|
||||
|
||||
void foo()
|
||||
{
|
||||
vec4 v = texelFetch(s2dr, itloc2);
|
||||
v += texelFetch(s2dr, itloc2, 0.2); // ERROR, no lod
|
||||
v += texture(s2dr, tloc2);
|
||||
v += texture(s2dr, tloc2, 0.3); // ERROR, no bias
|
||||
v += texture(s2drs, tloc3);
|
||||
v += textureProj(s2dr, tloc3);
|
||||
v += textureProj(s2dr, tloc4);
|
||||
v += textureProjGradOffset(s2dr, tloc4, ivec2(0.0), ivec2(0.0), ivec2(1,2));
|
||||
v += textureProjGradOffset(s2drs, tloc4, ivec2(0.0), ivec2(0.0), ivec2(1,2));
|
||||
}
|
||||
|
||||
void devi()
|
||||
{
|
||||
gl_DeviceIndex; // ERROR, no extension
|
||||
gl_ViewIndex; // ERROR, no extension
|
||||
}
|
||||
|
||||
#ifdef GL_EXT_device_group
|
||||
#extension GL_EXT_device_group : enable
|
||||
#endif
|
||||
|
||||
#ifdef GL_EXT_multiview
|
||||
#extension GL_EXT_multiview : enable
|
||||
#endif
|
||||
|
||||
void devie()
|
||||
{
|
||||
gl_DeviceIndex;
|
||||
gl_ViewIndex;
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
#version 150 core
|
||||
|
||||
in vec4 gl_FragCoord;
|
||||
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR
|
||||
layout(pixel_center_integer) in vec4 gl_FragCoord; // ERROR
|
||||
layout(origin_upper_left) in vec4 foo; // ERROR
|
||||
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c = gl_FragCoord;
|
||||
}
|
||||
|
||||
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR, declared after use
|
||||
|
||||
in struct S { float f; } s;
|
||||
|
||||
float patch = 3.1;
|
||||
|
||||
uniform sampler2DMS sms;
|
||||
uniform isampler2DMS isms;
|
||||
uniform usampler2DMS usms;
|
||||
uniform sampler2DMSArray smsa;
|
||||
uniform isampler2DMSArray ismsa;
|
||||
uniform usampler2DMSArray usmsa;
|
||||
|
||||
flat in ivec2 p2;
|
||||
flat in ivec3 p3;
|
||||
flat in int samp;
|
||||
|
||||
void barWxyz()
|
||||
{
|
||||
ivec2 t11 = textureSize( sms);
|
||||
ivec2 t12 = textureSize(isms);
|
||||
ivec2 t13 = textureSize(usms);
|
||||
ivec3 t21 = textureSize( smsa);
|
||||
ivec3 t22 = textureSize(ismsa);
|
||||
ivec3 t23 = textureSize(usmsa);
|
||||
vec4 t31 = texelFetch( sms, p2, samp);
|
||||
ivec4 t32 = texelFetch(isms, p2, samp);
|
||||
uvec4 t33 = texelFetch(usms, p2, 3);
|
||||
vec4 t41 = texelFetch( smsa, p3, samp);
|
||||
ivec4 t42 = texelFetch(ismsa, ivec3(2), samp);
|
||||
uvec4 t43 = texelFetch(usmsa, p3, samp);
|
||||
}
|
||||
|
||||
int primitiveID()
|
||||
{
|
||||
return gl_PrimitiveID;
|
||||
gl_PerFragment; // ERROR, block name can't get reused
|
||||
}
|
||||
|
||||
in double type1; // ERROR
|
||||
#extension GL_ARB_gpu_shader_fp64 : enable
|
||||
double type2;
|
||||
double type3 = 2.0;
|
||||
int absTest = sqrt(type3);
|
||||
double absTest2 = sqrt(type3);
|
||||
double absTest3 = sqrt(2);
|
||||
float dk = sqrt(11);
|
||||
|
||||
#extension GL_ARB_shader_bit_encoding: enable
|
||||
|
||||
float f;
|
||||
vec4 v4;
|
||||
ivec4 iv4a;
|
||||
uvec2 uv2c;
|
||||
void bitEncodingPass()
|
||||
{
|
||||
int i = floatBitsToInt(f);
|
||||
uvec4 uv11 = floatBitsToUint(v4);
|
||||
vec4 v14 = intBitsToFloat(iv4a);
|
||||
vec2 v15 = uintBitsToFloat(uv2c);
|
||||
}
|
||||
|
||||
#extension GL_ARB_shader_bit_encoding: disable
|
||||
|
||||
void bitEncodingFail()
|
||||
{
|
||||
int i = floatBitsToInt(f); // Error, extention GL_ARB_bit_encoding is diabled
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
#version 150 core
|
||||
|
||||
in fromVertex {
|
||||
in vec3 color;
|
||||
} fromV[];
|
||||
|
||||
out toFragment {
|
||||
out vec3 color;
|
||||
} toF;
|
||||
|
||||
out fromVertex { // okay to reuse a block name for another block name
|
||||
vec3 color;
|
||||
};
|
||||
|
||||
out fooB {
|
||||
vec2 color;
|
||||
} fromVertex; // ERROR, cannot reuse block name as block instance
|
||||
|
||||
int fromVertex; // ERROR, cannot reuse a block name for something else
|
||||
|
||||
out fooC {
|
||||
vec2 color;
|
||||
} fooC; // ERROR, cannot have same name for block and instance name
|
||||
|
||||
void main()
|
||||
{
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
EmitStreamVertex(1); // ERROR
|
||||
EndStreamPrimitive(0); // ERROR
|
||||
|
||||
color = fromV[0].color;
|
||||
gl_ClipDistance[3] = gl_in[1].gl_ClipDistance[2];
|
||||
gl_Position = gl_in[0].gl_Position;
|
||||
gl_PointSize = gl_in[3].gl_PointSize;
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
gl_Layer = 2;
|
||||
}
|
||||
|
||||
out vec4 ov0; // stream should be 0
|
||||
layout(stream = 4) out vec4 ov4;
|
||||
out vec4 o1v0; // stream should be 0
|
||||
|
||||
layout(stream = 3) uniform; // ERROR
|
||||
layout(stream = 3) in; // ERROR
|
||||
layout(stream = 3) uniform int ua; // ERROR
|
||||
layout(stream = 3) uniform ubb { int ua; } ibb; // ERROR
|
||||
|
||||
layout(line_strip, points, triangle_strip, stream = 3, points, triangle_strip) out; // just means "stream = 3, triangle_strip"
|
||||
layout(stream = 3, triangle_strip) out;
|
||||
out vec4 ov3; // stream should be 3
|
||||
|
||||
layout(stream = 6) out ooutb { vec4 a; } ouuaa6;
|
||||
|
||||
layout(stream = 6) out ooutb2 {
|
||||
layout(stream = 6) vec4 a;
|
||||
} ouua6;
|
||||
|
||||
layout(stream = 7) out ooutb3 {
|
||||
layout(stream = 6) vec4 a; // ERROR
|
||||
} ouua7;
|
||||
|
||||
out vec4 ov2s3; // stream should be 3
|
||||
|
||||
layout(max_vertices = 200) out;
|
||||
layout(max_vertices = 300) out; // ERROR, too big
|
||||
void foo(layout(max_vertices = 4) int a) // ERROR
|
||||
{
|
||||
ouuaa6.a = vec4(1.0);
|
||||
}
|
||||
|
||||
layout(line_strip, points, triangle_strip, stream = 3, points) out; // ERROR, changing output primitive
|
||||
layout(line_strip, points, stream = 3) out; // ERROR, changing output primitive
|
||||
layout(triangle_strip) in; // ERROR, not an input primitive
|
||||
layout(triangle_strip) uniform; // ERROR
|
||||
layout(triangle_strip) out vec4 badv4; // ERROR, not on a variable
|
||||
layout(triangle_strip) in vec4 bad2v4[]; // ERROR, not on a variable or input
|
||||
layout(invocations = 3) out outbn { int a; }; // 2 ERROR, not on a block, not until 4.0
|
||||
out outbn2 {
|
||||
layout(invocations = 3) int a; // 2 ERRORs, not on a block member, not until 4.0
|
||||
layout(max_vertices = 3) int b; // ERROR, not on a block member
|
||||
layout(triangle_strip) int c; // ERROR, not on a block member
|
||||
} outbi;
|
||||
|
||||
layout(lines) out; // ERROR, not on output
|
||||
layout(lines_adjacency) in;
|
||||
layout(triangles) in; // ERROR, can't change it
|
||||
layout(triangles_adjacency) in; // ERROR, can't change it
|
||||
layout(invocations = 4) in; // ERROR, not until 4.0
|
||||
|
||||
in inbn {
|
||||
layout(stream = 2) int a; // ERROR, stream on input
|
||||
} inbi[];
|
||||
|
||||
in sameName {
|
||||
int a15;
|
||||
} insn[];
|
||||
|
||||
out sameName {
|
||||
float f15;
|
||||
};
|
||||
|
||||
uniform sameName {
|
||||
bool b15;
|
||||
};
|
||||
|
||||
float summ = gl_MaxVertexAttribs +
|
||||
gl_MaxVertexUniformComponents +
|
||||
gl_MaxVaryingFloats +
|
||||
gl_MaxVaryingComponents +
|
||||
gl_MaxVertexOutputComponents +
|
||||
gl_MaxGeometryInputComponents +
|
||||
gl_MaxGeometryOutputComponents +
|
||||
gl_MaxFragmentInputComponents +
|
||||
gl_MaxVertexTextureImageUnits +
|
||||
gl_MaxCombinedTextureImageUnits +
|
||||
gl_MaxTextureImageUnits +
|
||||
gl_MaxFragmentUniformComponents +
|
||||
gl_MaxDrawBuffers +
|
||||
gl_MaxClipDistances +
|
||||
gl_MaxGeometryTextureImageUnits +
|
||||
gl_MaxGeometryOutputVertices +
|
||||
gl_MaxGeometryTotalOutputComponents +
|
||||
gl_MaxGeometryUniformComponents +
|
||||
gl_MaxGeometryVaryingComponents;
|
||||
|
||||
void fooe1()
|
||||
{
|
||||
gl_ViewportIndex = gl_MaxViewports - 1;
|
||||
}
|
||||
|
||||
#extension GL_ARB_viewport_array : enable
|
||||
|
||||
void fooe2()
|
||||
{
|
||||
gl_ViewportIndex = gl_MaxViewports - 1;
|
||||
}
|
||||
|
||||
out int gl_ViewportIndex;
|
|
@ -1,34 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#extension GL_ARB_tessellation_shader : enable
|
||||
|
||||
layout(vertices = 4) out;
|
||||
int outa[gl_out.length()];
|
||||
|
||||
patch out vec4 patchOut;
|
||||
|
||||
void main()
|
||||
{
|
||||
barrier();
|
||||
|
||||
int a = gl_MaxTessControlInputComponents +
|
||||
gl_MaxTessControlOutputComponents +
|
||||
gl_MaxTessControlTextureImageUnits +
|
||||
gl_MaxTessControlUniformComponents +
|
||||
gl_MaxTessControlTotalOutputComponents;
|
||||
|
||||
vec4 p = gl_in[1].gl_Position;
|
||||
float ps = gl_in[1].gl_PointSize;
|
||||
float cd = gl_in[1].gl_ClipDistance[2];
|
||||
|
||||
int pvi = gl_PatchVerticesIn;
|
||||
int pid = gl_PrimitiveID;
|
||||
int iid = gl_InvocationID;
|
||||
|
||||
gl_out[gl_InvocationID].gl_Position = p;
|
||||
gl_out[gl_InvocationID].gl_PointSize = ps;
|
||||
gl_out[gl_InvocationID].gl_ClipDistance[1] = cd;
|
||||
|
||||
gl_TessLevelOuter[3] = 3.2;
|
||||
gl_TessLevelInner[1] = 1.3;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
#version 150
|
||||
|
||||
#extension GL_ARB_tessellation_shader : enable
|
||||
|
||||
layout(quads, cw) in;
|
||||
layout(fractional_odd_spacing) in;
|
||||
layout(point_mode) in;
|
||||
patch in vec4 patchIn;
|
||||
|
||||
void main()
|
||||
{
|
||||
barrier(); // ERROR
|
||||
|
||||
int a = gl_MaxTessEvaluationInputComponents +
|
||||
gl_MaxTessEvaluationOutputComponents +
|
||||
gl_MaxTessEvaluationTextureImageUnits +
|
||||
gl_MaxTessEvaluationUniformComponents +
|
||||
gl_MaxTessPatchComponents +
|
||||
gl_MaxPatchVertices +
|
||||
gl_MaxTessGenLevel;
|
||||
|
||||
vec4 p = gl_in[1].gl_Position;
|
||||
float ps = gl_in[1].gl_PointSize;
|
||||
float cd = gl_in[1].gl_ClipDistance[2];
|
||||
|
||||
int pvi = gl_PatchVerticesIn;
|
||||
int pid = gl_PrimitiveID;
|
||||
vec3 tc = gl_TessCoord;
|
||||
float tlo = gl_TessLevelOuter[3];
|
||||
float tli = gl_TessLevelInner[1];
|
||||
|
||||
gl_Position = p;
|
||||
gl_PointSize = ps;
|
||||
gl_ClipDistance[2] = cd;
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
#version 150 core
|
||||
|
||||
#ifndef GL_core_profile
|
||||
# error standard macro GL_core_profile not defined
|
||||
#endif
|
||||
|
||||
in vec4 iv4;
|
||||
|
||||
uniform float ps;
|
||||
|
||||
invariant gl_Position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = iv4;
|
||||
gl_PointSize = ps;
|
||||
gl_ClipDistance[2] = iv4.x;
|
||||
gl_ClipVertex = iv4;
|
||||
}
|
||||
|
||||
out float gl_ClipDistance[4];
|
||||
|
||||
uniform foob {
|
||||
int a[];
|
||||
};
|
||||
int a[5]; // ERROR, resizing user-block member
|
||||
|
||||
#line 3000
|
||||
#error line of this error should be 3001
|
|
@ -1,161 +0,0 @@
|
|||
#version 300 es
|
||||
void nodef1(float f); // ERROR, no default precision
|
||||
uniform sampler2D s2D;
|
||||
uniform lowp sampler3D s3D;
|
||||
uniform samplerCube sCube;
|
||||
uniform lowp samplerCubeShadow sCubeShadow;
|
||||
uniform lowp sampler2DShadow s2DShadow;
|
||||
uniform lowp sampler2DArray s2DArray;
|
||||
uniform lowp sampler2DArrayShadow s2DArrayShadow;
|
||||
|
||||
uniform lowp isampler2D is2D;
|
||||
uniform lowp isampler3D is3D;
|
||||
uniform lowp isamplerCube isCube;
|
||||
uniform lowp isampler2DArray is2DArray;
|
||||
|
||||
uniform lowp usampler2D us2D;
|
||||
uniform lowp usampler3D us3D;
|
||||
uniform lowp usamplerCube usCube;
|
||||
uniform lowp usampler2DArray us2DArray;
|
||||
precision lowp float;
|
||||
in float c1D;
|
||||
in vec2 c2D;
|
||||
in vec3 c3D;
|
||||
smooth vec4 c4D;
|
||||
|
||||
flat in int ic1D;
|
||||
flat in ivec2 ic2D;
|
||||
flat in ivec3 ic3D;
|
||||
flat in ivec4 ic4D;
|
||||
noperspective in vec4 badv; // ERROR
|
||||
in sampler2D bads; // ERROR
|
||||
precision lowp uint; // ERROR
|
||||
|
||||
struct s {
|
||||
int i;
|
||||
sampler2D s;
|
||||
};
|
||||
|
||||
in s badout; // ERROR, can't contain a sampler
|
||||
// ERROR, can't have int in struct without flat
|
||||
struct S2 {
|
||||
vec3 c;
|
||||
float f;
|
||||
};
|
||||
|
||||
in S2 s2;
|
||||
|
||||
out vec3 sc;
|
||||
out float sf;
|
||||
|
||||
uniform sampler2D arrayedSampler[5];
|
||||
|
||||
void main()
|
||||
{
|
||||
float f;
|
||||
vec4 v;
|
||||
v = texture(s2D, c2D);
|
||||
v = textureProj(s3D, c4D);
|
||||
v = textureLod(s2DArray, c3D, 1.2);
|
||||
f = textureOffset(s2DShadow, c3D, ic2D, c1D); // ERROR, offset argument not constant
|
||||
v = texelFetch(s3D, ic3D, ic1D);
|
||||
v = texelFetchOffset(arrayedSampler[2], ic2D, 4, ic2D); // ERROR, offset argument not constant
|
||||
f = textureLodOffset(s2DShadow, c3D, c1D, ic2D);
|
||||
v = textureProjLodOffset(s2D, c3D, c1D, ic2D);
|
||||
v = textureGrad(sCube, c3D, c3D, c3D);
|
||||
f = textureGradOffset(s2DArrayShadow, c4D, c2D, c2D, ic2D);
|
||||
v = textureProjGrad(s3D, c4D, c3D, c3D);
|
||||
v = textureProjGradOffset(s2D, c3D, c2D, c2D, ic2D);
|
||||
v = texture(arrayedSampler[ic1D], c2D); // ERROR
|
||||
|
||||
ivec4 iv;
|
||||
iv = texture(is2D, c2D);
|
||||
iv = textureProjOffset(is2D, c4D, ic2D);
|
||||
iv = textureProjLod(is2D, c3D, c1D);
|
||||
iv = textureProjGrad(is2D, c3D, c2D, c2D);
|
||||
iv = texture(is3D, c3D, 4.2);
|
||||
iv = textureLod(isCube, c3D, c1D);
|
||||
iv = texelFetch(is2DArray, ic3D, ic1D);
|
||||
|
||||
iv.xy = textureSize(sCubeShadow, 2);
|
||||
|
||||
float precise;
|
||||
double boo; // ERROR
|
||||
dvec2 boo2; // ERROR
|
||||
dvec3 boo3; // ERROR
|
||||
dvec4 boo4; // ERROR
|
||||
|
||||
f += gl_FragCoord.y;
|
||||
gl_FragDepth = f;
|
||||
|
||||
sc = s2.c;
|
||||
sf = s2.f;
|
||||
|
||||
sinh(c1D) +
|
||||
cosh(c1D) * tanh(c2D);
|
||||
asinh(c4D) + acosh(c4D);
|
||||
atanh(c3D);
|
||||
}
|
||||
|
||||
uniform multi {
|
||||
int[2] a[3]; // ERROR
|
||||
int[2][3] b; // ERROR
|
||||
int c[2][3]; // ERROR
|
||||
} multiInst[2][3]; // ERROR
|
||||
|
||||
out vec4 colors[4];
|
||||
|
||||
void foo()
|
||||
{
|
||||
colors[2] = c4D;
|
||||
colors[ic1D] = c4D; // ERROR
|
||||
}
|
||||
|
||||
uniform s st1;
|
||||
uniform s st2;
|
||||
|
||||
void foo13(s inSt2)
|
||||
{
|
||||
if (st1 == st2); // ERROR
|
||||
if (st1 != st2); // ERROR
|
||||
st1.s == st2.s; // ERROR
|
||||
inSt2 = st1; // ERROR
|
||||
inSt2 == st1; // ERROR
|
||||
}
|
||||
|
||||
void foo23()
|
||||
{
|
||||
textureOffset(s2DShadow, c3D, ivec2(-8, 7), c1D);
|
||||
textureOffset(s2DShadow, c3D, ivec2(-9, 8), c1D);
|
||||
}
|
||||
|
||||
void foo324(void)
|
||||
{
|
||||
float p = pow(3.2, 4.6);
|
||||
p += sin(0.4);
|
||||
p += distance(vec2(10.0, 11.0), vec2(13.0, 15.0)); // 5
|
||||
p += dot(vec3(2,3,5), vec3(-2,-1,4)); // 13
|
||||
vec3 c3 = cross(vec3(3,-3,1), vec3(4,9,2)); // (-15, -2, 39)
|
||||
c3 += faceforward(vec3(1,2,3), vec3(2,3,5), vec3(-2,-1,4)); // (-1,-2,-3)
|
||||
c3 += faceforward(vec3(1,2,3), vec3(-2,-3,-5), vec3(-2,-1,4)); // (1,2,3)
|
||||
vec2 c2 = reflect(vec2(1,3), vec2(0,1)); // (1,-3)
|
||||
c2 += refract(vec2(1,3), vec2(0,1), 1.0); // (1,-3)
|
||||
c2 += refract(vec2(1,3), vec2(0,1), 3.0);
|
||||
c2 += refract(vec2(1,0.1), vec2(0,1), 5.0); // (0,0)
|
||||
mat3x2 m32 = outerProduct(vec2(2,3), vec3(5,7,11));// rows: (10, 14, 22), (15, 21, 33)
|
||||
}
|
||||
|
||||
uniform mediump; // ERROR
|
||||
|
||||
layout(early_fragment_tests) in; // ERROR
|
||||
|
||||
#ifndef GL_FRAGMENT_PRECISION_HIGH
|
||||
#error missing GL_FRAGMENT_PRECISION_HIGH
|
||||
#endif
|
||||
|
||||
invariant in; // ERROR
|
||||
invariant in vec4; // ERROR
|
||||
invariant in vec4 fooinv; // ERROR
|
||||
|
||||
float imageBuffer; // ERROR, reserved
|
||||
float uimage2DRect; // ERROR, reserved
|
|
@ -1,204 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
uniform mat4x3 m43;
|
||||
uniform mat3x3 m33;
|
||||
uniform mat4x4 m44;
|
||||
|
||||
in vec3 v3;
|
||||
varying vec2 v2; // ERROR, varying reserved
|
||||
in vec4 bad[10]; // ERROR, no arrayed inputs
|
||||
highp in vec4 badorder; // ERROR, incorrect qualifier order
|
||||
out invariant vec4 badorder2; // ERROR, incorrect qualifier order
|
||||
in centroid vec4 badorder4; // ERROR, incorrect qualifier order
|
||||
out flat vec4 badorder3; // ERROR, incorrect qualifier order
|
||||
void bar(in const float a); // ERROR, incorrect qualifier order
|
||||
void bar2(highp in float b); // ERROR, incorrect qualifier order
|
||||
smooth flat out vec4 rep; // ERROR, replicating interpolation qualification
|
||||
centroid sample out vec4 rep2; // ERROR, replicating auxiliary qualification
|
||||
in uniform vec4 rep3; // ERROR, replicating storage qualification
|
||||
|
||||
struct S {
|
||||
vec3 c;
|
||||
float f;
|
||||
};
|
||||
|
||||
out S s;
|
||||
|
||||
void main()
|
||||
{
|
||||
int id = gl_VertexID + gl_InstanceID;
|
||||
|
||||
int c0 = gl_MaxVertexAttribs;
|
||||
int c1 = gl_MaxVertexUniformVectors;
|
||||
int c2 = gl_MaxVertexOutputVectors;
|
||||
int c3 = gl_MaxFragmentInputVectors;
|
||||
int c4 = gl_MaxVertexTextureImageUnits;
|
||||
int c5 = gl_MaxCombinedTextureImageUnits;
|
||||
int c6 = gl_MaxTextureImageUnits;
|
||||
int c7 = gl_MaxFragmentUniformVectors;
|
||||
int c8 = gl_MaxDrawBuffers;
|
||||
int c9 = gl_MinProgramTexelOffset;
|
||||
int c10 = gl_MaxProgramTexelOffset;
|
||||
|
||||
mat3x4 tm = transpose(m43);
|
||||
highp float dm = determinant(m44);
|
||||
mat3x3 im = inverse(m33);
|
||||
|
||||
mat3x2 op = outerProduct(v2, v3);
|
||||
|
||||
gl_Position = m44[2];
|
||||
gl_PointSize = v2.y;
|
||||
|
||||
s.c = v3;
|
||||
s.f = dm;
|
||||
|
||||
#ifdef GL_ES
|
||||
#error GL_ES is set
|
||||
#else
|
||||
#error GL_ES is not set
|
||||
#endif
|
||||
}
|
||||
|
||||
float badsize[]; // ERROR
|
||||
float[] badsize2; // ERROR
|
||||
uniform ub {
|
||||
int a[]; // ERROR
|
||||
} ubInst[]; // ERROR
|
||||
void foo(int a[]); // ERROR
|
||||
float okayA[] = float[](3.0f, 4.0F); // Okay
|
||||
|
||||
out vec3 newV;
|
||||
void newVFun()
|
||||
{
|
||||
newV = v3;
|
||||
}
|
||||
|
||||
invariant newV; // ERROR, variable already used
|
||||
in vec4 invIn;
|
||||
invariant invIn; // ERROR, in v300
|
||||
out S s2;
|
||||
invariant s2;
|
||||
invariant out S s3;
|
||||
flat out int;
|
||||
|
||||
uniform ub2 {
|
||||
float f;
|
||||
} a;
|
||||
|
||||
uniform ub2 { // ERROR redeclaration of block name (same instance name)
|
||||
float g;
|
||||
} a;
|
||||
|
||||
uniform ub2 { // ERROR redeclaration of block name (different instance name)
|
||||
float f;
|
||||
} c;
|
||||
|
||||
uniform ub2 { // ERROR redeclaration of block name (no instance name)
|
||||
float f123;
|
||||
};
|
||||
|
||||
uniform ub3 {
|
||||
bool b23;
|
||||
};
|
||||
|
||||
uniform ub3 { // ERROR redeclaration of block name (no instance name in first or declared)
|
||||
bool b234;
|
||||
};
|
||||
|
||||
precision lowp sampler3D;
|
||||
precision lowp sampler2DShadow;
|
||||
precision lowp sampler2DArrayShadow;
|
||||
|
||||
uniform sampler2D s2D;
|
||||
uniform sampler3D s3D;
|
||||
uniform sampler2DShadow s2DS;
|
||||
uniform sampler2DArrayShadow s2DAS;
|
||||
in vec2 c2D;
|
||||
|
||||
void foo23()
|
||||
{
|
||||
ivec2 x1 = textureSize(s2D, 2);
|
||||
textureSize(s2D); // ERROR, no lod
|
||||
ivec3 x3 = textureSize(s2DAS, -1);
|
||||
textureSize(s2DAS); // ERROR, no lod
|
||||
vec4 x4 = texture(s2D, c2D);
|
||||
texture(s2D, c2D, 0.2); // ERROR, bias
|
||||
vec4 x5 = textureProjOffset(s3D, vec4(0.2), ivec3(1));
|
||||
textureProjOffset(s3D, vec4(0.2), ivec3(1), .03); // ERROR, bias
|
||||
float x6 = textureProjGradOffset(s2DS, invIn, vec2(4.2), vec2(5.3), ivec2(1));
|
||||
}
|
||||
|
||||
int fgfg(float f, mediump int i);
|
||||
int fgfg(float f, highp int i); // ERROR, precision qualifier difference
|
||||
|
||||
int fgfgh(float f, const in mediump int i);
|
||||
int fgfgh(float f, in mediump int i); // ERROR, precision qualifier difference
|
||||
|
||||
void foo2349()
|
||||
{
|
||||
float[] x = float[] (1.0, 2.0, 3.0);
|
||||
float[] y = x;
|
||||
float[3] z = x;
|
||||
float[3] w;
|
||||
w = y;
|
||||
}
|
||||
|
||||
int[] foo213234(); // ERROR
|
||||
int foo234234(float[]); // ERROR
|
||||
int foo234235(vec2[] v); // ERROR
|
||||
precision highp float[2]; // ERROR
|
||||
|
||||
int fffg(float f);
|
||||
int fffg(float f);
|
||||
|
||||
int gggf(float f);
|
||||
int gggf(float f) { return 2; }
|
||||
int gggf(float f);
|
||||
|
||||
int agggf(float f) { return 2; }
|
||||
int agggf(float f);
|
||||
|
||||
out struct Ssss { float f; } ssss;
|
||||
|
||||
uniform Bblock {
|
||||
int a;
|
||||
} Binst;
|
||||
int Bfoo;
|
||||
|
||||
layout(std140) Binst; // ERROR
|
||||
layout(std140) Bblock; // ERROR
|
||||
layout(std140) Bfoo; // ERROR
|
||||
|
||||
layout(std430) uniform B430 { int a; } B430i; // ERROR
|
||||
|
||||
struct SNA {
|
||||
int a[]; // ERROR
|
||||
};
|
||||
|
||||
void fooDeeparray()
|
||||
{
|
||||
float[] x = float[] (1.0, 2.0, 3.0),
|
||||
y = float[] (1.0, 2.0, 3.0, 4.0);
|
||||
float xp[3], yp[4];
|
||||
xp = x;
|
||||
yp = y;
|
||||
xp = y; // ERROR, wrong size
|
||||
yp = x; // ERROR, wrong size
|
||||
}
|
||||
|
||||
layout(num_views = 2) in; // ERROR, no extension
|
||||
|
||||
void mwErr()
|
||||
{
|
||||
gl_ViewID_OVR; // ERROR, no extension
|
||||
}
|
||||
|
||||
#extension GL_OVR_multiview : enable
|
||||
|
||||
layout(num_views = 2) uniform float mwUniform; // ERROR, must be global
|
||||
layout(num_views = 2) in; // OK
|
||||
|
||||
void mwOk()
|
||||
{
|
||||
gl_ViewID_OVR;
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
int imax, imin;
|
||||
uint umax, umin;
|
||||
|
||||
vec3 x, y; // ERROR, needs default precision
|
||||
bvec3 bv;
|
||||
|
||||
uint uy;
|
||||
uvec2 uv2c;
|
||||
uvec2 uv2y;
|
||||
uvec2 uv2x;
|
||||
uvec4 uv4y;
|
||||
|
||||
ivec3 iv3a;
|
||||
ivec3 iv3b;
|
||||
|
||||
ivec4 iv4a;
|
||||
ivec4 iv4b;
|
||||
|
||||
float f;
|
||||
|
||||
vec2 v2a, v2b;
|
||||
vec4 v4;
|
||||
|
||||
void main()
|
||||
{
|
||||
// 1.3 int
|
||||
vec3 v = mix(x, y, bv);
|
||||
ivec4 iv10 = abs(iv4a);
|
||||
ivec4 iv11 = sign(iv4a);
|
||||
ivec4 iv12 = min(iv4a, iv4b);
|
||||
ivec4 iv13 = min(iv4a, imin);
|
||||
uvec2 u = min(uv2x, uv2y);
|
||||
uvec4 uv = min(uv4y, uy);
|
||||
ivec3 iv14 = max(iv3a, iv3b);
|
||||
ivec4 iv15 = max(iv4a, imax);
|
||||
uvec2 u10 = max(uv2x, uv2y);
|
||||
uvec2 u11 = max(uv2x, uy);
|
||||
ivec4 iv16 = clamp(iv4a, iv4a, iv4b);
|
||||
ivec4 iv17 = clamp(iv4a, imin, imax);
|
||||
uvec2 u12 = clamp(uv2x, uv2y, uv2c);
|
||||
uvec4 uv10 = clamp(uv4y, umin, umax);
|
||||
|
||||
// 1.3 float
|
||||
vec3 modfOut;
|
||||
vec3 v11 = modf(x, modfOut);
|
||||
|
||||
float t = trunc(f);
|
||||
vec2 v12 = round(v2a);
|
||||
vec2 v13 = roundEven(v2a);
|
||||
bvec2 b10 = isnan(v2a);
|
||||
bvec4 b11 = isinf(v4);
|
||||
|
||||
// 3.3 float
|
||||
int i = floatBitsToInt(f);
|
||||
uvec4 uv11 = floatBitsToUint(v4);
|
||||
vec4 v14 = intBitsToFloat(iv4a);
|
||||
vec2 v15 = uintBitsToFloat(uv2c);
|
||||
|
||||
// 4.0 pack
|
||||
uint u19 = packSnorm2x16(v2a);
|
||||
vec2 v20 = unpackSnorm2x16(uy);
|
||||
uint u15 = packUnorm2x16(v2a);
|
||||
vec2 v16 = unpackUnorm2x16(uy);
|
||||
uint u17 = packHalf2x16(v2b);
|
||||
vec2 v18 = unpackHalf2x16(uy);
|
||||
|
||||
// not present
|
||||
noise2(v18); // ERROR, not present
|
||||
|
||||
float t__; // ERROR, no __ until revision 310
|
||||
|
||||
// ERROR, no __ until revision 310
|
||||
#define __D
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
precision mediump float;
|
||||
|
||||
struct S {
|
||||
vec4 u;
|
||||
uvec4 v;
|
||||
lowp isampler3D sampler;
|
||||
vec3 w;
|
||||
struct T1 { // ERROR
|
||||
int a;
|
||||
} t;
|
||||
};
|
||||
|
||||
uniform S s;
|
||||
|
||||
uniform fooBlock {
|
||||
uvec4 bv;
|
||||
uniform mat2 bm2;
|
||||
lowp isampler2D sampler; // ERROR
|
||||
struct T2 { // ERROR
|
||||
int a;
|
||||
} t;
|
||||
S fbs; // ERROR, contains a sampler
|
||||
};
|
||||
|
||||
uniform barBlock {
|
||||
uvec4 nbv;
|
||||
int ni;
|
||||
} inst;
|
||||
|
||||
uniform barBlockArray {
|
||||
uvec4 nbv;
|
||||
int ni;
|
||||
} insts[4];
|
||||
|
||||
uniform unreferenced {
|
||||
float f;
|
||||
uint u;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
texture(s.sampler, vec3(inst.ni, bv.y, insts[2].nbv.z));
|
||||
insts[s.v.x]; // ERROR
|
||||
fooBlock; // ERROR
|
||||
mat4(s); // ERROR
|
||||
int insts;
|
||||
float barBlock;
|
||||
mat4(barBlock);
|
||||
mat4(unreferenced); // ERROR, bad type
|
||||
++s; // ERROR
|
||||
inst - 1; // ERROR
|
||||
++barBlock;
|
||||
2 * barBlockArray; // ERROR
|
||||
}
|
||||
|
||||
int fooBlock; // ERROR, redef.
|
|
@ -1,19 +0,0 @@
|
|||
#version 300 es
|
||||
precision mediump float;
|
||||
in vec4 pos;
|
||||
layout (location = 2) in vec4 color; // ERROR
|
||||
|
||||
layout(location = 1) out vec4 c;
|
||||
layout(location = 3) out vec4 p;
|
||||
layout(location = 4) out vec4 q[2];
|
||||
|
||||
void main()
|
||||
{
|
||||
c = color;
|
||||
p = pos;
|
||||
q[1] = pos;
|
||||
}
|
||||
|
||||
layout(location = 40) out float ca[4]; // ERROR, overlap, ERROR too big
|
||||
layout(location = 41) out float cb[2]; // ERROR, overlap, ERROR too big
|
||||
layout(location = 39) out float cc[6]; // ERROR, overlap, ERROR too big
|
|
@ -1,57 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
struct s { vec4 v; };
|
||||
|
||||
layout(location = 7) in vec3 c;
|
||||
layout(LocatioN = 3) in vec4 p;
|
||||
layout(LocatioN = 9) in vec4 q[4]; // ERROR, no array
|
||||
layout(LocatioN = 10) in s r[4]; // ERROR, no struct, ERROR, location overlap
|
||||
out vec4 pos;
|
||||
out vec3 color;
|
||||
|
||||
layout(shared, column_major) uniform mat4 badm4; // ERROR
|
||||
layout(shared, column_major, row_major) uniform; // default is now shared and row_major
|
||||
|
||||
layout(std140) uniform Transform { // layout of this block is std140
|
||||
mat4 M1; // row_major
|
||||
layout(column_major) mat4 M2; // column major
|
||||
mat3 N1; // row_major
|
||||
centroid float badf; // ERROR
|
||||
in float badg; // ERROR
|
||||
layout(std140) float bad1;
|
||||
layout(shared) float bad2;
|
||||
layout(packed) float bad3;
|
||||
} tblock;
|
||||
|
||||
uniform T2 { // layout of this block is shared
|
||||
bool b;
|
||||
mat4 t2m;
|
||||
};
|
||||
|
||||
layout(column_major) uniform T3 { // shared and column_major
|
||||
mat4 M3; // column_major
|
||||
layout(row_major) mat4 M4; // row major
|
||||
mat3 N2; // column_major
|
||||
int b; // ERROR, redefinition (needs to be last member of block for testing, following members are skipped)
|
||||
};
|
||||
|
||||
out badout { // ERROR
|
||||
float f;
|
||||
};
|
||||
|
||||
layout (location = 10) out vec4 badoutA; // ERROR
|
||||
|
||||
void main()
|
||||
{
|
||||
pos = p * (tblock.M1 + tblock.M2 + M4 + M3 + t2m);
|
||||
color = c * tblock.N1;
|
||||
}
|
||||
|
||||
shared vec4 compute_only; // ERROR
|
||||
|
||||
layout(packed) uniform;
|
||||
|
||||
layout(packed) uniform float aoeuntaoeu; // ERROR, packed on variable
|
||||
|
||||
layout(location = 40) in float cd;
|
||||
layout(location = 37) in mat4x3 ce; // ERROR, overlap
|
|
@ -1,8 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
|
||||
out vec4 color1;
|
||||
out vec4 color2;
|
||||
|
||||
void main() {}
|
|
@ -1,11 +0,0 @@
|
|||
#version 300 es
|
||||
precision mediump float;
|
||||
in vec4 pos;
|
||||
|
||||
layout(location = 1) out vec4 c;
|
||||
layout(location = 5) out vec4 p;
|
||||
layout(location = 9) out vec4 q[2];
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
|
||||
out vec4 color1;
|
||||
|
||||
void main() {}
|
|
@ -1,135 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
uniform block {
|
||||
mediump float f;
|
||||
} instanceName;
|
||||
|
||||
struct S {
|
||||
int i;
|
||||
} s;
|
||||
|
||||
float a[5];
|
||||
|
||||
void main()
|
||||
{
|
||||
bool b;
|
||||
float f;
|
||||
int i;
|
||||
uint u;
|
||||
bvec3 b3;
|
||||
vec3 v3;
|
||||
ivec3 iv3;
|
||||
uvec3 uv3;
|
||||
vec4 v4;
|
||||
ivec4 iv4;
|
||||
uvec4 uv4;
|
||||
mat2 m2;
|
||||
mat4 m4;
|
||||
|
||||
// These are all errors:
|
||||
instanceName + instanceName;
|
||||
s + s;
|
||||
i + f;
|
||||
u + f;
|
||||
u + i;
|
||||
iv3 *= iv4;
|
||||
iv4 / uv4;
|
||||
i - v3;
|
||||
iv3 + uv3;
|
||||
a * a;
|
||||
b / b;
|
||||
|
||||
f % f;
|
||||
i % f;
|
||||
f % u;
|
||||
instanceName++;
|
||||
++s;
|
||||
a--;
|
||||
++b3;
|
||||
|
||||
iv3 < uv3;
|
||||
m2 > m2;
|
||||
m2 != m4;
|
||||
i >= u;
|
||||
a <= a;
|
||||
b > b;
|
||||
|
||||
b && b3;
|
||||
b3 ^^ b3;
|
||||
b3 || b;
|
||||
i && i;
|
||||
u || u;
|
||||
m2 ^^ m2;
|
||||
|
||||
!u;
|
||||
!i;
|
||||
!m2;
|
||||
!v3;
|
||||
!a;
|
||||
|
||||
~f;
|
||||
~m4;
|
||||
~v3;
|
||||
~a;
|
||||
~instanceName;
|
||||
|
||||
i << iv3;
|
||||
u << uv3;
|
||||
i >> f;
|
||||
f >> i;
|
||||
m4 >> i;
|
||||
a >> u;
|
||||
iv3 >> iv4;
|
||||
|
||||
i & u;
|
||||
u &= uv3;
|
||||
i | uv3;
|
||||
u & f;
|
||||
m2 | m2;
|
||||
s ^ s;
|
||||
(f = f) = f;
|
||||
|
||||
// These are all okay:
|
||||
f * v4;
|
||||
u + u;
|
||||
uv4 / u;
|
||||
iv3 -= iv3;
|
||||
|
||||
i %= 3;
|
||||
uv3 % 4u;
|
||||
--m2;
|
||||
iv4++;
|
||||
|
||||
m4 != m4;
|
||||
m2 == m2;
|
||||
i <= i;
|
||||
a == a;
|
||||
s != s;
|
||||
|
||||
b && b;
|
||||
b || b;
|
||||
b ^^ b;
|
||||
|
||||
!b, uv3;
|
||||
|
||||
~i;
|
||||
~u;
|
||||
~uv3;
|
||||
~iv3;
|
||||
|
||||
uv3 <<= i;
|
||||
i >> i;
|
||||
u << u;
|
||||
iv3 >> iv3;
|
||||
|
||||
i & i;
|
||||
u | u;
|
||||
iv3 ^ iv3;
|
||||
u & uv3;
|
||||
uv3 | u;
|
||||
uv3 &= u;
|
||||
int arr[0x222 & 0xf];
|
||||
arr[1]; // size 2
|
||||
int arr2[(uvec2(0, 0x2) | 0x1u).y];
|
||||
arr2[2]; // size 3
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
#extension GL_OES_EGL_image_external_essl3 : enable
|
||||
|
||||
uniform samplerExternalOES sExt;
|
||||
precision mediump samplerExternalOES;
|
||||
uniform samplerExternalOES mediumExt;
|
||||
uniform highp samplerExternalOES highExt;
|
||||
|
||||
void main()
|
||||
{
|
||||
texture2D(sExt, vec2(0.2)); // ERROR
|
||||
texture2D(mediumExt, vec2(0.2)); // ERROR
|
||||
texture2D(highExt, vec2(0.2)); // ERROR
|
||||
texture2DProj(sExt, vec3(0.3)); // ERROR
|
||||
texture2DProj(sExt, vec4(0.3)); // ERROR
|
||||
|
||||
int lod = 0;
|
||||
highp float bias = 0.01;
|
||||
textureSize(sExt, lod);
|
||||
texture(sExt, vec2(0.2));
|
||||
texture(sExt, vec2(0.2), bias);
|
||||
textureProj(sExt, vec3(0.2));
|
||||
textureProj(sExt, vec3(0.2), bias);
|
||||
textureProj(sExt, vec4(0.2));
|
||||
textureProj(sExt, vec4(0.2), bias);
|
||||
texelFetch(sExt, ivec2(4), lod);
|
||||
|
||||
texture3D(sExt, vec3(0.3)); // ERROR
|
||||
texture2DProjLod(sExt, vec3(0.3), 0.3); // ERROR
|
||||
texture(sExt, vec3(0.3)); // ERROR
|
||||
textureProjLod(sExt, vec3(0.3), 0.3); // ERROR
|
||||
}
|
||||
|
||||
#extension GL_OES_EGL_image_external_essl3 : disable
|
||||
|
||||
#extension GL_OES_EGL_image_external : enable
|
||||
uniform samplerExternalOES badExt; // ERROR
|
||||
#extension GL_OES_EGL_image_external : disable
|
||||
|
||||
uniform samplerExternalOES badExt; // ERROR
|
|
@ -1,38 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
#extension GL_EXT_YUV_target : enable
|
||||
|
||||
uniform __samplerExternal2DY2YEXT sExt;
|
||||
precision mediump __samplerExternal2DY2YEXT;
|
||||
uniform __samplerExternal2DY2YEXT mediumExt;
|
||||
uniform highp __samplerExternal2DY2YEXT highExt;
|
||||
|
||||
void main()
|
||||
{
|
||||
texture2D(sExt, vec2(0.2)); // ERROR
|
||||
texture2D(mediumExt, vec2(0.2)); // ERROR
|
||||
texture2D(highExt, vec2(0.2)); // ERROR
|
||||
texture2DProj(sExt, vec3(0.3)); // ERROR
|
||||
texture2DProj(sExt, vec4(0.3)); // ERROR
|
||||
|
||||
int lod = 0;
|
||||
highp float bias = 0.01;
|
||||
textureSize(sExt, lod);
|
||||
texture(sExt, vec2(0.2));
|
||||
texture(sExt, vec2(0.2), bias);
|
||||
textureProj(sExt, vec3(0.2));
|
||||
textureProj(sExt, vec3(0.2), bias);
|
||||
textureProj(sExt, vec4(0.2));
|
||||
textureProj(sExt, vec4(0.2), bias);
|
||||
texelFetch(sExt, ivec2(4), lod);
|
||||
|
||||
texture3D(sExt, vec3(0.3)); // ERROR
|
||||
texture2DProjLod(sExt, vec3(0.3), 0.3); // ERROR
|
||||
texture(sExt, vec3(0.3)); // ERROR
|
||||
textureProjLod(sExt, vec3(0.3), 0.3); // ERROR
|
||||
}
|
||||
|
||||
#extension GL_EXT_YUV_target : disable
|
||||
|
||||
uniform __samplerExternal2DY2YEXT badExt; // ERROR
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
#version 300 es
|
||||
|
||||
int f(int a, int b, int c)
|
||||
{
|
||||
int a = b; // ERROR, redefinition
|
||||
|
||||
{
|
||||
float a = float(a) + 1.0;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int f(int a, int b, int c); // okay to redeclare
|
||||
|
||||
bool b;
|
||||
float b(int a); // ERROR: redefinition
|
||||
|
||||
float c(int a);
|
||||
bool c; // ERROR: redefinition
|
||||
|
||||
float f; // ERROR: redefinition
|
||||
float tan; // ERROR: redefines built-in function
|
||||
float sin(float x); // ERROR: can't redefine built-in functions
|
||||
float cos(float x) // ERROR: can't redefine built-in functions
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
bool radians(bool x) // ERROR: can't overload built-in functions
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
invariant gl_Position;
|
||||
|
||||
void main()
|
||||
{
|
||||
int g(); // ERROR: no local function declarations
|
||||
g();
|
||||
|
||||
float sin; // okay
|
||||
sin;
|
||||
sin(0.7); // ERROR, use of hidden function
|
||||
f(1,2,3);
|
||||
|
||||
float f; // hides f()
|
||||
f = 3.0;
|
||||
|
||||
gl_Position = vec4(f);
|
||||
|
||||
for (int f = 0; f < 10; ++f)
|
||||
++f;
|
||||
|
||||
int x = 1;
|
||||
{
|
||||
float x = 2.0, /* 2nd x visible here */ y = x; // y is initialized to 2
|
||||
int z = z; // ERROR: z not previously defined.
|
||||
}
|
||||
{
|
||||
int x = x; // x is initialized to '1'
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int x;
|
||||
};
|
||||
{
|
||||
S S = S(0); // 'S' is only visible as a struct and constructor
|
||||
S.x; // 'S' is now visible as a variable
|
||||
}
|
||||
|
||||
int degrees;
|
||||
degrees(3.2); // ERROR, use of hidden built-in function
|
||||
}
|
|
@ -1,256 +0,0 @@
|
|||
#version 310 es
|
||||
|
||||
layout(local_size_x = 2) in;
|
||||
layout(local_size_x = 16) in; // ERROR, changing
|
||||
layout(local_size_z = 4096) in; // ERROR, too large
|
||||
layout(local_size_x = 2) in;
|
||||
layout(local_size_y = 0) in; // ERROR, 0 not allowed
|
||||
const int total = gl_MaxComputeWorkGroupCount.y
|
||||
+ gl_MaxComputeUniformComponents
|
||||
+ gl_MaxComputeTextureImageUnits
|
||||
+ gl_MaxComputeImageUniforms
|
||||
+ gl_MaxComputeAtomicCounters
|
||||
+ gl_MaxComputeAtomicCounterBuffers;
|
||||
|
||||
buffer ShaderStorageBlock
|
||||
{
|
||||
int value;
|
||||
float values[];
|
||||
};
|
||||
|
||||
buffer InvalidShaderStorageBlock
|
||||
{
|
||||
float values[]; // ERROR
|
||||
int value;
|
||||
} invalid;
|
||||
|
||||
void main()
|
||||
{
|
||||
barrier();
|
||||
memoryBarrier();
|
||||
memoryBarrierAtomicCounter();
|
||||
memoryBarrierBuffer();
|
||||
memoryBarrierShared();
|
||||
memoryBarrierImage();
|
||||
groupMemoryBarrier();
|
||||
value = int(values[gl_LocalInvocationIndex]);
|
||||
}
|
||||
|
||||
layout(location = 2) in vec3 v3; // ERROR
|
||||
in float f; // ERROR
|
||||
out float fo; // ERROR
|
||||
|
||||
shared vec4 s;
|
||||
layout(location = 2) shared vec4 sl; // ERROR
|
||||
shared float fs = 4.2; // ERROR
|
||||
|
||||
layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) out; // ERROR
|
||||
|
||||
int arrX[gl_WorkGroupSize.x];
|
||||
int arrY[gl_WorkGroupSize.y];
|
||||
int arrZ[gl_WorkGroupSize.z];
|
||||
|
||||
readonly buffer roblock
|
||||
{
|
||||
int value;
|
||||
float values[];
|
||||
} ro;
|
||||
|
||||
void foo()
|
||||
{
|
||||
ro.values[2] = 4.7; // ERROR, readonly
|
||||
ro.values.length();
|
||||
++s;
|
||||
}
|
||||
|
||||
buffer vec4 v; // ERROR
|
||||
|
||||
uniform usampler2D us2dbad; // ERROR, default precision
|
||||
|
||||
precision highp usampler2D;
|
||||
precision highp iimage2DArray;
|
||||
precision highp iimage2D;
|
||||
|
||||
uniform usampler2D us2d;
|
||||
|
||||
uniform iimage2DArray ii2dabad; // ERROR, not writeonly
|
||||
uniform writeonly iimage2DArray ii2da;
|
||||
|
||||
layout(r32i) uniform iimage2D iimg2D;
|
||||
layout(rgba32i) uniform readonly iimage2D iimg2Drgba;
|
||||
layout(rgba32f) uniform readonly image2D img2Drgba; // ERROR, no default
|
||||
layout(r32ui) uniform uimage2D uimg2D; // ERROR, no default
|
||||
|
||||
void qux()
|
||||
{
|
||||
int i = 4;
|
||||
imageAtomicCompSwap(iimg2D, ivec2(i,i), i, i);// ERROR no longer in 310
|
||||
imageAtomicAdd(uimg2D, ivec2(i,i), uint(i)); // ERROR no longer in 310
|
||||
imageAtomicMin(iimg2Drgba, ivec2(i,i), i); // ERROR no longer in 310 // ERROR iimg2Drgba does not have r32i layout
|
||||
imageAtomicMax(img2Drgba, ivec2(i,i), i); // ERROR no longer in 310 // ERROR img2Drgba is not integer image
|
||||
ivec4 pos = imageLoad(iimg2D, ivec2(i,i));
|
||||
imageStore(ii2da, ivec3(i,i,i), ivec4(0));
|
||||
imageLoad(img2Drgba, ivec2(i,i));
|
||||
imageLoad(ii2da, ivec3(i,i,i)); // ERROR, drops writeonly
|
||||
}
|
||||
|
||||
volatile float vol; // ERROR, not an image
|
||||
readonly int vol2; // ERROR, not an image
|
||||
|
||||
void passr(coherent readonly iimage2D image)
|
||||
{
|
||||
}
|
||||
|
||||
layout(r32i) coherent readonly uniform iimage2D qualim1;
|
||||
layout(r32i) coherent restrict readonly uniform iimage2D qualim2;
|
||||
|
||||
void passrc()
|
||||
{
|
||||
passr(qualim1); // ERROR, changing formats
|
||||
passr(qualim2); // ERROR, drops restrict, ERROR, changing formats
|
||||
passr(iimg2D); // ERROR, changing formats
|
||||
}
|
||||
|
||||
highp layout(rg8i) uniform readonly uimage2D i1bad; // ERROR, type mismatch
|
||||
highp layout(rgba32i) uniform readonly image2D i2bad; // ERROR, type mismatch
|
||||
highp layout(rgba32f) uniform readonly uimage2D i3bad; // ERROR, type mismatch
|
||||
layout(r8_snorm) uniform readonly iimage2D i4bad; // ERROR, type mismatch
|
||||
layout(rgba32ui) uniform readonly iimage2D i5bad; // ERROR, type mismatch
|
||||
layout(r8ui) uniform readonly iimage2D i6bad; // ERROR, type mismatch
|
||||
|
||||
layout(binding = 0) uniform atomic_uint counter;
|
||||
|
||||
uint func(atomic_uint c)
|
||||
{
|
||||
return atomicCounterIncrement(c);
|
||||
}
|
||||
|
||||
uint func2(out atomic_uint c) // ERROR, output
|
||||
{
|
||||
return counter; // ERROR, type mismatch
|
||||
return atomicCounter(counter);
|
||||
}
|
||||
|
||||
void mainAC()
|
||||
{
|
||||
atomic_uint non_uniform_counter; // ERROR
|
||||
uint val = atomicCounter(counter);
|
||||
atomicCounterDecrement(counter);
|
||||
}
|
||||
|
||||
layout(binding = 1) uniform mediump atomic_uint counterBad; // ERROR, not highp
|
||||
|
||||
layout(binding = 2, offset = 4) uniform atomic_uint countArr[4];
|
||||
uniform int i;
|
||||
|
||||
void opac()
|
||||
{
|
||||
int a[3];
|
||||
a[counter]; // ERROR, non-integer
|
||||
countArr[2];
|
||||
countArr[i];
|
||||
}
|
||||
|
||||
shared int atomi;
|
||||
shared uint atomu;
|
||||
|
||||
void atoms()
|
||||
{
|
||||
int origi = atomicAdd(atomi, 3);
|
||||
uint origu = atomicAnd(atomu, 7u);
|
||||
origi = atomicExchange(atomi, 4);
|
||||
origu = atomicCompSwap(atomu, 10u, 8u);
|
||||
}
|
||||
|
||||
precision highp atomic_uint;
|
||||
precision lowp atomic_uint; // ERROR
|
||||
|
||||
precise int pfoo; // ERROR, reserved
|
||||
|
||||
dmat2x4 dm; // ERROR
|
||||
uniform samplerCubeArray sca; // ERROR
|
||||
uniform iimage2DRect i2dr; // ERROR
|
||||
highp uniform image2DMS i2dms; // ERROR
|
||||
uniform uimage2DMSArray u2dmsa; // ERROR
|
||||
|
||||
highp layout(r32f) coherent volatile restrict readonly writeonly uniform image2D okay1;
|
||||
layout(r32i) coherent volatile restrict readonly uniform iimage2D okay2;
|
||||
highp layout(r32ui) coherent volatile restrict writeonly uniform uimage2D okay3;
|
||||
highp layout(r32f) coherent volatile restrict uniform image2D okay4;
|
||||
|
||||
highp layout(rgba32f) coherent volatile restrict uniform image2D badQ1; // ERROR, bad qualifiers
|
||||
layout(rgba8i) coherent volatile restrict uniform iimage2D badQ2; // ERROR, bad qualifiers
|
||||
highp layout(rgba16ui) coherent volatile restrict uniform uimage2D badQ3; // ERROR, bad qualifiers
|
||||
|
||||
writeonly buffer woblock
|
||||
{
|
||||
int value;
|
||||
float values[];
|
||||
} wo;
|
||||
|
||||
void foowo()
|
||||
{
|
||||
float g;
|
||||
g = wo.values[2]; // ERROR, writeonly
|
||||
float f = wo.values[2]; // ERROR, writeonly
|
||||
++wo.values[2]; // ERROR, writeonly
|
||||
wo.values[2]--; // ERROR, writeonly
|
||||
f + wo.values[2]; // ERROR, writeonly
|
||||
wo.values[2] - f; // ERROR, writeonly
|
||||
bool b;
|
||||
b ? f : wo.values[2]; // ERROR, writeonly
|
||||
b ? wo.values[2] : f; // ERROR, writeonly
|
||||
if (f == wo.values[2]) // ERROR, writeonly
|
||||
++f;
|
||||
if (f >= wo.values[2]) // ERROR, writeonly
|
||||
++f;
|
||||
f = vec3(wo.values[2]).x; // ERROR, writeonly
|
||||
~wo.value; // ERROR, writeonly
|
||||
wo.values[2] = 3.4;
|
||||
}
|
||||
|
||||
buffer multioblock
|
||||
{
|
||||
readonly int value;
|
||||
writeonly float values[];
|
||||
} multio;
|
||||
|
||||
void foomultio()
|
||||
{
|
||||
float g;
|
||||
g = wo.values[2]; // ERROR, writeonly
|
||||
~wo.value;
|
||||
wo.values[2] = 3.4;
|
||||
wo.value = 2; // ERROR, readonly
|
||||
}
|
||||
|
||||
in inb { // ERROR
|
||||
int a;
|
||||
} inbi;
|
||||
|
||||
out outb { // ERROR
|
||||
int a;
|
||||
} outbi;
|
||||
|
||||
float t__; // ERROR, no __ until revision 310
|
||||
|
||||
// ERROR, no __ until revision 310
|
||||
#define __D
|
||||
|
||||
shared vec4 arr[2][3][4];
|
||||
|
||||
void devi()
|
||||
{
|
||||
gl_DeviceIndex; // ERROR, no extension
|
||||
gl_ViewIndex; // ERROR, never this stage
|
||||
}
|
||||
|
||||
#ifdef GL_EXT_device_group
|
||||
#extension GL_EXT_device_group : enable
|
||||
#endif
|
||||
|
||||
void devie()
|
||||
{
|
||||
gl_DeviceIndex;
|
||||
gl_ViewIndex; // ERROR, never this stage
|
||||
}
|
|
@ -1,451 +0,0 @@
|
|||
#version 310 es
|
||||
highp float nodef3(float); // ERROR, no default precision
|
||||
precision mediump float;
|
||||
precision highp usampler2D;
|
||||
precision highp sampler2D;
|
||||
precision highp isampler2DArray;
|
||||
|
||||
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR, not supported
|
||||
|
||||
layout(location = 2) in vec3 v3;
|
||||
layout(location = 2) in mat4 yi; // ERROR, locations conflict with xi
|
||||
|
||||
uniform sampler2D arrayedSampler[5];
|
||||
uniform usampler2D usamp2d;
|
||||
uniform usampler2DRect samp2dr; // ERROR, reserved
|
||||
uniform isampler2DArray isamp2DA;
|
||||
|
||||
in vec2 c2D;
|
||||
uniform int i;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 v = texture(arrayedSampler[i], c2D); // ERROR
|
||||
|
||||
ivec2 offsets[4];
|
||||
const ivec2 constOffsets[4] = ivec2[4](ivec2(1,2), ivec2(3,4), ivec2(15,16), ivec2(-2,0));
|
||||
uvec4 uv4 = textureGatherOffsets(samp2dr, c2D, offsets, 2); // ERROR, not supported
|
||||
vec4 v4 = textureGather(arrayedSampler[0], c2D);
|
||||
ivec4 iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 3);
|
||||
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), i); // ERROR, last argument not const
|
||||
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 4); // ERROR, last argument out of range
|
||||
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(1), 1+2);
|
||||
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(0.5));
|
||||
iv4 = textureGatherOffset(isamp2DA, vec3(0.1), ivec2(i)); // ERROR, offset not constant
|
||||
}
|
||||
|
||||
out vec4 outp;
|
||||
void foo23()
|
||||
{
|
||||
const ivec2[3] offsets = ivec2[3](ivec2(1,2), ivec2(3,4), ivec2(15,16));
|
||||
|
||||
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), ivec2(c2D)); // ERROR, offset not constant
|
||||
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[1]);
|
||||
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), offsets[2]); // ERROR, offset out of range
|
||||
textureProjGradOffset(usamp2d, outp, vec2(0.0), vec2(0.0), ivec2(-10, 20)); // ERROR, offset out of range
|
||||
|
||||
if (gl_HelperInvocation)
|
||||
++outp;
|
||||
|
||||
int sum = gl_MaxVertexImageUniforms +
|
||||
gl_MaxFragmentImageUniforms +
|
||||
gl_MaxComputeImageUniforms +
|
||||
gl_MaxCombinedImageUniforms +
|
||||
gl_MaxCombinedShaderOutputResources;
|
||||
|
||||
bool b1, b2, b3, b;
|
||||
|
||||
b1 = mix(b2, b3, b);
|
||||
uvec3 um3 = mix(uvec3(i), uvec3(i), bvec3(b));
|
||||
ivec4 im4 = mix(ivec4(i), ivec4(i), bvec4(b));
|
||||
1 << mix(1u, 1u, false); // does not require folding
|
||||
}
|
||||
layout(binding=3) uniform sampler2D s1;
|
||||
layout(binding=3) uniform sampler2D s2; // ERROR: overlapping bindings? Don't see that in the 310 spec.
|
||||
highp layout(binding=2) uniform writeonly image2D i2D;
|
||||
layout(binding=4) uniform readonly image3D i3D; // ERROR, no default precision
|
||||
layout(binding=5) uniform imageCube iCube; // ERROR, no default precision
|
||||
layout(binding=6) uniform image2DArray i2DA; // ERROR, no default precision
|
||||
layout(binding=6) uniform coherent volatile restrict image2D i2Dqualified; // ERROR, no default precision
|
||||
|
||||
layout(binding = 1) uniform bb {
|
||||
int foo;
|
||||
layout(binding = 2) float f; // ERROR
|
||||
} bbi;
|
||||
|
||||
in centroid vec4 centroidIn;
|
||||
layout(location = 200000) uniform vec4 bigl; // ERROR, location too big
|
||||
|
||||
layout(early_fragment_tests) in;
|
||||
|
||||
layout(location = 40) out vec4 bigout1; // ERROR, too big
|
||||
layout(location = 40) out vec4 bigout2; // ERROR, overlap
|
||||
layout(location = -2) out vec4 neg; // ERROR, negative
|
||||
|
||||
layout(std430) buffer b430 {
|
||||
int i;
|
||||
} b430i;
|
||||
|
||||
layout(shared) uniform bshar {
|
||||
int i;
|
||||
} bshari;
|
||||
|
||||
in smooth vec4 smoothIn;
|
||||
in flat int flatIn;
|
||||
|
||||
uniform sampler2DMS s2dms; // ERROR, no default precision qualifier
|
||||
|
||||
void foots()
|
||||
{
|
||||
highp ivec2 v2 = textureSize(s1, 2);
|
||||
highp ivec3 v3 = textureSize(isamp2DA, 3);
|
||||
v2 = textureSize(s2dms);
|
||||
v2 = imageSize(i2D);
|
||||
v3 = imageSize(i3D);
|
||||
v2 = imageSize(iCube);
|
||||
v3 = imageSize(i2DA);
|
||||
v2 = imageSize(i2Dqualified);
|
||||
}
|
||||
|
||||
out bool bout; // ERROR
|
||||
highp out image2D imageOut; // ERROR
|
||||
out mat2x3 mout; // ERROR
|
||||
|
||||
in bool inb; // ERROR
|
||||
in sampler2D ino; // ERROR
|
||||
in float ina[4];
|
||||
in float inaa[4][2]; // ERROR
|
||||
struct S { float f; };
|
||||
in S ins;
|
||||
in S[4] inasa; // ERROR
|
||||
in S insa[4]; // ERROR
|
||||
struct SA { float f[4]; };
|
||||
in SA inSA; // ERROR
|
||||
struct SS { float f; S s; };
|
||||
in SS inSS; // ERROR
|
||||
|
||||
#ifndef GL_EXT_shader_io_blocks
|
||||
#error GL_EXT_shader_io_blocks not defined
|
||||
#endif
|
||||
|
||||
#extension GL_EXT_shader_io_blocks : enable
|
||||
|
||||
out outbname { int a; } outbinst; // ERROR, not out block in fragment shader
|
||||
|
||||
in inbname {
|
||||
int a;
|
||||
vec4 v;
|
||||
struct { int b; } s; // ERROR, nested struct definition
|
||||
} inbinst;
|
||||
|
||||
in inbname2 {
|
||||
layout(location = 12) int aAnon;
|
||||
layout(location = 13) centroid in vec4 vAnon;
|
||||
};
|
||||
|
||||
in layout(location = 13) vec4 aliased; // ERROR, aliased
|
||||
|
||||
in inbname2 { // ERROR, reuse of block name
|
||||
int aAnon;
|
||||
centroid in vec4 vAnon;
|
||||
};
|
||||
|
||||
in badmember { // ERROR, aAnon already in global scope
|
||||
int aAnon;
|
||||
};
|
||||
|
||||
int inbname; // ERROR, redefinition of block name
|
||||
|
||||
vec4 vAnon; // ERROR, anon in global scope; redefinition
|
||||
|
||||
in arrayed {
|
||||
float f;
|
||||
} arrayedInst[4];
|
||||
|
||||
void fooIO()
|
||||
{
|
||||
vec4 v = inbinst.v + vAnon;
|
||||
v *= arrayedInst[2].f;
|
||||
v *= arrayedInst[i].f;
|
||||
}
|
||||
|
||||
in vec4 gl_FragCoord;
|
||||
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR, non-ES
|
||||
|
||||
layout(early_fragment_tests) in;
|
||||
out float gl_FragDepth;
|
||||
layout(depth_any) out float gl_FragDepth; // ERROR, non-ES
|
||||
|
||||
void foo_IO()
|
||||
{
|
||||
gl_FragDepth = 0.2; // ERROR, early_fragment_tests declared
|
||||
gl_Layer; // ERROR, not present
|
||||
gl_PrimitiveID; // ERROR, not present
|
||||
bool f = gl_FrontFacing;
|
||||
}
|
||||
|
||||
out float gl_FragDepth;
|
||||
|
||||
#extension GL_OES_geometry_shader : enable
|
||||
|
||||
void foo_GS()
|
||||
{
|
||||
highp int l = gl_Layer;
|
||||
highp int p = gl_PrimitiveID;
|
||||
}
|
||||
|
||||
in vec2 inf, ing;
|
||||
uniform ivec2 offsets[4];
|
||||
uniform sampler2D sArray[4];
|
||||
uniform int sIndex;
|
||||
layout(binding = 0) uniform atomic_uint auArray[2];
|
||||
uniform ubName { int i; } ubInst[4];
|
||||
buffer bbName { int i; } bbInst[4];
|
||||
highp uniform writeonly image2D iArray[5];
|
||||
const ivec2 constOffsets[4] = ivec2[4](ivec2(0.1), ivec2(0.2), ivec2(0.3), ivec2(0.4));
|
||||
|
||||
void pfooBad()
|
||||
{
|
||||
precise vec2 h; // ERROR reserved
|
||||
h = fma(inf, ing, h); // ERROR, not available
|
||||
textureGatherOffset(sArray[0], vec2(0.1), ivec2(inf)); // ERROR, offset not constant
|
||||
textureGatherOffsets(sArray[0], vec2(0.1), constOffsets); // ERROR, not available
|
||||
}
|
||||
|
||||
#extension GL_OES_gpu_shader5 : enable
|
||||
|
||||
void pfoo()
|
||||
{
|
||||
precise vec2 h;
|
||||
h = fma(inf, ing, h);
|
||||
textureGatherOffset(sArray[0], vec2(0.1), ivec2(inf));
|
||||
textureGatherOffsets(sArray[0], vec2(0.1), constOffsets);
|
||||
textureGatherOffsets(sArray[0], vec2(0.1), offsets); // ERROR, offset not constant
|
||||
}
|
||||
|
||||
#extension GL_EXT_texture_cube_map_array : enable
|
||||
|
||||
precision highp imageCubeArray ;
|
||||
precision highp iimageCubeArray ;
|
||||
precision highp uimageCubeArray ;
|
||||
|
||||
precision highp samplerCubeArray ;
|
||||
precision highp samplerCubeArrayShadow;
|
||||
precision highp isamplerCubeArray ;
|
||||
precision highp usamplerCubeArray ;
|
||||
|
||||
uniform writeonly imageCubeArray CA1;
|
||||
uniform writeonly iimageCubeArray CA2;
|
||||
uniform writeonly uimageCubeArray CA3;
|
||||
|
||||
#ifdef GL_EXT_texture_cube_map_array
|
||||
uniform samplerCubeArray CA4;
|
||||
uniform samplerCubeArrayShadow CA5;
|
||||
uniform isamplerCubeArray CA6;
|
||||
uniform usamplerCubeArray CA7;
|
||||
#endif
|
||||
|
||||
void CAT()
|
||||
{
|
||||
highp vec4 b4 = texture(CA4, vec4(0.5), 0.24);
|
||||
highp ivec4 b6 = texture(CA6, vec4(0.5), 0.26);
|
||||
highp uvec4 b7 = texture(CA7, vec4(0.5), 0.27);
|
||||
}
|
||||
|
||||
void badSample()
|
||||
{
|
||||
lowp int a1 = gl_SampleID; // ERROR, need extension
|
||||
mediump vec2 a2 = gl_SamplePosition; // ERROR, need extension
|
||||
highp int a3 = gl_SampleMaskIn[0]; // ERROR, need extension
|
||||
gl_SampleMask[0] = a3; // ERROR, need extension
|
||||
mediump int n = gl_NumSamples; // ERROR, need extension
|
||||
}
|
||||
|
||||
#ifdef GL_OES_sample_variables
|
||||
#extension GL_OES_sample_variables : enable
|
||||
#endif
|
||||
|
||||
void goodSample()
|
||||
{
|
||||
lowp int a1 = gl_SampleID;
|
||||
mediump vec2 a2 = gl_SamplePosition;
|
||||
highp int a3 = gl_SampleMaskIn[0];
|
||||
gl_SampleMask[0] = a3;
|
||||
mediump int n1 = gl_MaxSamples;
|
||||
mediump int n2 = gl_NumSamples;
|
||||
}
|
||||
|
||||
uniform layout(r32f) highp image2D im2Df;
|
||||
uniform layout(r32ui) highp uimage2D im2Du;
|
||||
uniform layout(r32i) highp iimage2D im2Di;
|
||||
uniform ivec2 P;
|
||||
|
||||
void badImageAtom()
|
||||
{
|
||||
float datf;
|
||||
int dati;
|
||||
uint datu;
|
||||
|
||||
imageAtomicAdd( im2Di, P, dati); // ERROR, need extension
|
||||
imageAtomicAdd( im2Du, P, datu); // ERROR, need extension
|
||||
imageAtomicMin( im2Di, P, dati); // ERROR, need extension
|
||||
imageAtomicMin( im2Du, P, datu); // ERROR, need extension
|
||||
imageAtomicMax( im2Di, P, dati); // ERROR, need extension
|
||||
imageAtomicMax( im2Du, P, datu); // ERROR, need extension
|
||||
imageAtomicAnd( im2Di, P, dati); // ERROR, need extension
|
||||
imageAtomicAnd( im2Du, P, datu); // ERROR, need extension
|
||||
imageAtomicOr( im2Di, P, dati); // ERROR, need extension
|
||||
imageAtomicOr( im2Du, P, datu); // ERROR, need extension
|
||||
imageAtomicXor( im2Di, P, dati); // ERROR, need extension
|
||||
imageAtomicXor( im2Du, P, datu); // ERROR, need extension
|
||||
imageAtomicExchange(im2Di, P, dati); // ERROR, need extension
|
||||
imageAtomicExchange(im2Du, P, datu); // ERROR, need extension
|
||||
imageAtomicExchange(im2Df, P, datf); // ERROR, need extension
|
||||
imageAtomicCompSwap(im2Di, P, 3, dati); // ERROR, need extension
|
||||
imageAtomicCompSwap(im2Du, P, 5u, datu); // ERROR, need extension
|
||||
}
|
||||
|
||||
#ifdef GL_OES_shader_image_atomic
|
||||
#extension GL_OES_shader_image_atomic : enable
|
||||
#endif
|
||||
|
||||
uniform layout(rgba32f) highp image2D badIm2Df; // ERROR, needs readonly or writeonly
|
||||
uniform layout(rgba8ui) highp uimage2D badIm2Du; // ERROR, needs readonly or writeonly
|
||||
uniform layout(rgba16i) highp iimage2D badIm2Di; // ERROR, needs readonly or writeonly
|
||||
|
||||
void goodImageAtom()
|
||||
{
|
||||
float datf;
|
||||
int dati;
|
||||
uint datu;
|
||||
|
||||
imageAtomicAdd( im2Di, P, dati);
|
||||
imageAtomicAdd( im2Du, P, datu);
|
||||
imageAtomicMin( im2Di, P, dati);
|
||||
imageAtomicMin( im2Du, P, datu);
|
||||
imageAtomicMax( im2Di, P, dati);
|
||||
imageAtomicMax( im2Du, P, datu);
|
||||
imageAtomicAnd( im2Di, P, dati);
|
||||
imageAtomicAnd( im2Du, P, datu);
|
||||
imageAtomicOr( im2Di, P, dati);
|
||||
imageAtomicOr( im2Du, P, datu);
|
||||
imageAtomicXor( im2Di, P, dati);
|
||||
imageAtomicXor( im2Du, P, datu);
|
||||
imageAtomicExchange(im2Di, P, dati);
|
||||
imageAtomicExchange(im2Du, P, datu);
|
||||
imageAtomicExchange(im2Df, P, datf);
|
||||
imageAtomicCompSwap(im2Di, P, 3, dati);
|
||||
imageAtomicCompSwap(im2Du, P, 5u, datu);
|
||||
|
||||
imageAtomicMax(badIm2Di, P, dati); // ERROR, not an allowed layout() on the image
|
||||
imageAtomicMax(badIm2Du, P, datu); // ERROR, not an allowed layout() on the image
|
||||
imageAtomicExchange(badIm2Df, P, datf); // ERROR, not an allowed layout() on the image
|
||||
}
|
||||
|
||||
sample in vec4 colorSampInBad; // ERROR, reserved
|
||||
centroid out vec4 colorCentroidBad; // ERROR
|
||||
flat out vec4 colorBadFlat; // ERROR
|
||||
smooth out vec4 colorBadSmooth; // ERROR
|
||||
noperspective out vec4 colorBadNo; // ERROR
|
||||
flat centroid in vec2 colorfc;
|
||||
in float scalarIn;
|
||||
|
||||
void badInterp()
|
||||
{
|
||||
interpolateAtCentroid(colorfc); // ERROR, need extension
|
||||
interpolateAtSample(colorfc, 1); // ERROR, need extension
|
||||
interpolateAtOffset(colorfc, vec2(0.2)); // ERROR, need extension
|
||||
}
|
||||
|
||||
#if defined GL_OES_shader_multisample_interpolation
|
||||
#extension GL_OES_shader_multisample_interpolation : enable
|
||||
#endif
|
||||
|
||||
sample in vec4 colorSampIn;
|
||||
sample out vec4 colorSampleBad; // ERROR
|
||||
flat sample in vec4 colorfsi;
|
||||
sample in vec3 sampInArray[4];
|
||||
|
||||
void interp()
|
||||
{
|
||||
float res;
|
||||
vec2 res2;
|
||||
vec3 res3;
|
||||
vec4 res4;
|
||||
|
||||
res2 = interpolateAtCentroid(colorfc);
|
||||
res4 = interpolateAtCentroid(colorSampIn);
|
||||
res4 = interpolateAtCentroid(colorfsi);
|
||||
res = interpolateAtCentroid(scalarIn);
|
||||
res3 = interpolateAtCentroid(sampInArray); // ERROR
|
||||
res3 = interpolateAtCentroid(sampInArray[2]);
|
||||
res2 = interpolateAtCentroid(sampInArray[2].xy); // ERROR
|
||||
|
||||
res3 = interpolateAtSample(sampInArray, 1); // ERROR
|
||||
res3 = interpolateAtSample(sampInArray[i], 0);
|
||||
res2 = interpolateAtSample(sampInArray[2].xy, 2); // ERROR
|
||||
res = interpolateAtSample(scalarIn, 1);
|
||||
|
||||
res3 = interpolateAtOffset(sampInArray, vec2(0.2)); // ERROR
|
||||
res3 = interpolateAtOffset(sampInArray[2], vec2(0.2));
|
||||
res2 = interpolateAtOffset(sampInArray[2].xy, vec2(0.2)); // ERROR, no swizzle
|
||||
res = interpolateAtOffset(scalarIn + scalarIn, vec2(0.2)); // ERROR, no binary ops other than dereference
|
||||
res = interpolateAtOffset(scalarIn, vec2(0.2));
|
||||
|
||||
float f;
|
||||
res = interpolateAtCentroid(f); // ERROR, not interpolant
|
||||
res4 = interpolateAtSample(outp, 0); // ERROR, not interpolant
|
||||
}
|
||||
|
||||
layout(blend_support_softlight) out; // ERROR, need extension
|
||||
|
||||
#ifdef GL_KHR_blend_equation_advanced
|
||||
#extension GL_KHR_blend_equation_advanced : enable
|
||||
#endif
|
||||
|
||||
layout(blend_support_multiply) out;
|
||||
layout(blend_support_screen) out;
|
||||
layout(blend_support_overlay) out;
|
||||
layout(blend_support_darken, blend_support_lighten) out;
|
||||
layout(blend_support_colordodge) layout(blend_support_colorburn) out;
|
||||
layout(blend_support_hardlight) out;
|
||||
layout(blend_support_softlight) out;
|
||||
layout(blend_support_difference) out;
|
||||
layout(blend_support_exclusion) out;
|
||||
layout(blend_support_hsl_hue) out;
|
||||
layout(blend_support_hsl_saturation) out;
|
||||
layout(blend_support_hsl_color) out;
|
||||
layout(blend_support_hsl_luminosity) out;
|
||||
layout(blend_support_all_equations) out;
|
||||
|
||||
layout(blend_support_hsl_luminosity) out; // okay to repeat
|
||||
|
||||
layout(blend_support_hsl_luminosity) in; // ERROR, only on "out"
|
||||
layout(blend_support_hsl_luminosity) out vec4; // ERROR, only on standalone
|
||||
layout(blend_support_hsl_luminosity) out vec4 badout; // ERROR, only on standalone
|
||||
layout(blend_support_hsl_luminosity) struct badS {int i;}; // ERROR, only on standalone
|
||||
layout(blend_support_hsl_luminosity) void blendFoo() { } // ERROR, only on standalone
|
||||
void blendFoo(layout(blend_support_hsl_luminosity) vec3 v) { } // ERROR, only on standalone
|
||||
layout(blend_support_flizbit) out; // ERROR, no flizbit
|
||||
|
||||
out vec4 outAA[2][2]; // ERROR
|
||||
|
||||
void devi()
|
||||
{
|
||||
gl_DeviceIndex; // ERROR, no extension
|
||||
gl_ViewIndex; // ERROR, no extension
|
||||
}
|
||||
|
||||
#ifdef GL_EXT_device_group
|
||||
#extension GL_EXT_device_group : enable
|
||||
#endif
|
||||
|
||||
#ifdef GL_EXT_multiview
|
||||
#extension GL_EXT_multiview : enable
|
||||
#endif
|
||||
|
||||
void devie()
|
||||
{
|
||||
gl_DeviceIndex;
|
||||
gl_ViewIndex;
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
#version 310 es
|
||||
|
||||
#ifdef GL_EXT_geometry_shader
|
||||
#extension GL_EXT_geometry_shader : enable
|
||||
#else
|
||||
#error no GL_EXT_geometry_shader
|
||||
#endif
|
||||
|
||||
#ifndef GL_OES_geometry_shader
|
||||
#error no GL_OES_geometry_shader
|
||||
#endif
|
||||
|
||||
precision mediump float;
|
||||
|
||||
in fromVertex {
|
||||
in vec3 color;
|
||||
} fromV[];
|
||||
|
||||
in vec4 nonBlockUnsized[];
|
||||
|
||||
out toFragment {
|
||||
out vec3 color;
|
||||
} toF;
|
||||
|
||||
out fromVertex { // okay to reuse a block name for another block name
|
||||
vec3 color;
|
||||
};
|
||||
|
||||
out fooB { // ERROR, cannot reuse block name as block instance
|
||||
vec2 color;
|
||||
} fromVertex;
|
||||
|
||||
int fromVertex; // ERROR, cannot reuse a block name for something else
|
||||
|
||||
out fooC { // ERROR, cannot have same name for block and instance name
|
||||
vec2 color;
|
||||
} fooC;
|
||||
|
||||
void main()
|
||||
{
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
EmitStreamVertex(1); // ERROR
|
||||
EndStreamPrimitive(0); // ERROR
|
||||
|
||||
color = fromV[0].color;
|
||||
gl_ClipDistance[3] = // ERROR, no ClipDistance
|
||||
gl_in[1].gl_ClipDistance[2]; // ERROR, no ClipDistance
|
||||
gl_Position = gl_in[0].gl_Position;
|
||||
|
||||
gl_PrimitiveID = gl_PrimitiveIDIn;
|
||||
gl_Layer = 2;
|
||||
}
|
||||
|
||||
layout(stream = 4) out vec4 ov4; // ERROR, no streams
|
||||
|
||||
layout(line_strip, points, triangle_strip, points, triangle_strip) out; // just means triangle_strip"
|
||||
|
||||
out ooutb { vec4 a; } ouuaa6;
|
||||
|
||||
layout(max_vertices = 200) out;
|
||||
layout(max_vertices = 300) out; // ERROR, too big
|
||||
void foo(layout(max_vertices = 4) int a) // ERROR
|
||||
{
|
||||
ouuaa6.a = vec4(1.0);
|
||||
}
|
||||
|
||||
layout(line_strip, points, triangle_strip, points) out; // ERROR, changing output primitive
|
||||
layout(line_strip, points) out; // ERROR, changing output primitive
|
||||
layout(triangle_strip) in; // ERROR, not an input primitive
|
||||
layout(triangle_strip) uniform; // ERROR
|
||||
layout(triangle_strip) out vec4 badv4; // ERROR, not on a variable
|
||||
layout(triangle_strip) in vec4 bad2v4[]; // ERROR, not on a variable or input
|
||||
layout(invocations = 3) out outbn { int a; }; // 2 ERROR, not on a block, not until 4.0
|
||||
out outbn2 {
|
||||
layout(invocations = 3) int a; // 2 ERRORs, not on a block member, not until 4.0
|
||||
layout(max_vertices = 3) int b; // ERROR, not on a block member
|
||||
layout(triangle_strip) int c; // ERROR, not on a block member
|
||||
} outbi;
|
||||
|
||||
layout(lines) out; // ERROR, not on output
|
||||
layout(lines_adjacency) in;
|
||||
layout(triangles) in; // ERROR, can't change it
|
||||
layout(triangles_adjacency) in; // ERROR, can't change it
|
||||
layout(invocations = 4) in;
|
||||
|
||||
in sameName {
|
||||
int a15;
|
||||
} insn[];
|
||||
|
||||
out sameName {
|
||||
float f15;
|
||||
};
|
||||
|
||||
uniform sameName {
|
||||
bool b15;
|
||||
};
|
||||
|
||||
const int summ = gl_MaxVertexAttribs +
|
||||
gl_MaxGeometryInputComponents +
|
||||
gl_MaxGeometryOutputComponents +
|
||||
gl_MaxGeometryImageUniforms +
|
||||
gl_MaxGeometryTextureImageUnits +
|
||||
gl_MaxGeometryOutputVertices +
|
||||
gl_MaxGeometryTotalOutputComponents +
|
||||
gl_MaxGeometryUniformComponents +
|
||||
gl_MaxGeometryAtomicCounters +
|
||||
gl_MaxGeometryAtomicCounterBuffers +
|
||||
gl_MaxVertexTextureImageUnits +
|
||||
gl_MaxCombinedTextureImageUnits +
|
||||
gl_MaxTextureImageUnits +
|
||||
gl_MaxDrawBuffers;
|
||||
|
||||
void fooe1()
|
||||
{
|
||||
gl_ViewportIndex; // ERROR, not in ES
|
||||
gl_MaxViewports; // ERROR, not in ES
|
||||
insn.length(); // 4: lines_adjacency
|
||||
int inv = gl_InvocationID;
|
||||
}
|
||||
|
||||
in vec4 explArray[4];
|
||||
in vec4 explArrayBad[5]; // ERROR, wrong size
|
||||
in vec4 nonArrayed; // ERROR, not an array
|
||||
flat out vec3 myColor1;
|
||||
centroid out vec3 myColor2;
|
||||
centroid in vec3 centr[];
|
||||
sample out vec4 perSampleColor; // ERROR without sample extensions
|
||||
|
||||
layout(max_vertices = 200) out; // matching redecl
|
||||
|
||||
layout(location = 7, component = 2) in float comp[]; // ERROR, es has no component
|
||||
|
||||
void notHere()
|
||||
{
|
||||
gl_MaxGeometryVaryingComponents; // ERROR, not in ES
|
||||
gl_VerticesIn; // ERROR, not in ES
|
||||
}
|
||||
|
||||
void pointSize1()
|
||||
{
|
||||
highp float ps = gl_in[3].gl_PointSize; // ERROR, need point_size extension
|
||||
gl_PointSize = ps; // ERROR, need point_size extension
|
||||
}
|
||||
|
||||
#extension GL_OES_geometry_point_size : enable
|
||||
|
||||
void pointSize2()
|
||||
{
|
||||
highp float ps = gl_in[3].gl_PointSize;
|
||||
gl_PointSize = ps;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
struct S {
|
||||
float buff[10];
|
||||
};
|
||||
|
||||
layout(std430, binding=2) readonly buffer RoBuff {
|
||||
float buff_ro[10];
|
||||
S s_ro;
|
||||
} ro_buffer;
|
||||
|
||||
layout(std430, binding=2) buffer Buff {
|
||||
float buff[10];
|
||||
S s;
|
||||
} non_ro_buffer;
|
||||
|
||||
void non_ro_fun(float[10] buff) { }
|
||||
void non_ro_funf(float el) { }
|
||||
void non_ro_funS(S s) { }
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
S s;
|
||||
|
||||
non_ro_fun(s.buff);
|
||||
non_ro_funf(s.buff[3]);
|
||||
non_ro_funS(s);
|
||||
|
||||
non_ro_fun(non_ro_buffer.buff);
|
||||
non_ro_fun(non_ro_buffer.s.buff);
|
||||
non_ro_funf(non_ro_buffer.buff[3]);
|
||||
non_ro_funf(non_ro_buffer.s.buff[3]);
|
||||
non_ro_funS(non_ro_buffer.s);
|
||||
|
||||
non_ro_fun(ro_buffer.buff_ro);
|
||||
non_ro_fun(ro_buffer.s_ro.buff);
|
||||
non_ro_funf(ro_buffer.buff_ro[3]);
|
||||
non_ro_funf(ro_buffer.s_ro.buff[3]);
|
||||
non_ro_funS(ro_buffer.s_ro);
|
||||
}
|
|
@ -1,184 +0,0 @@
|
|||
#version 310 es
|
||||
|
||||
#extension GL_OES_tessellation_shader : enable
|
||||
|
||||
layout(vertices = 4) out;
|
||||
out int outa[gl_out.length()];
|
||||
|
||||
layout(quads) in; // ERROR
|
||||
layout(ccw) out; // ERROR
|
||||
layout(fractional_even_spacing) in; // ERROR
|
||||
|
||||
patch in vec4 patchIn; // ERROR
|
||||
patch out vec4 patchOut;
|
||||
|
||||
void main()
|
||||
{
|
||||
barrier();
|
||||
|
||||
int a = gl_MaxTessControlInputComponents +
|
||||
gl_MaxTessControlOutputComponents +
|
||||
gl_MaxTessControlTextureImageUnits +
|
||||
gl_MaxTessControlUniformComponents +
|
||||
gl_MaxTessControlTotalOutputComponents;
|
||||
|
||||
vec4 p = gl_in[1].gl_Position;
|
||||
float ps = gl_in[1].gl_PointSize; // ERROR, need point_size extension
|
||||
float cd = gl_in[1].gl_ClipDistance[2]; // ERROR, not in ES
|
||||
|
||||
int pvi = gl_PatchVerticesIn;
|
||||
int pid = gl_PrimitiveID;
|
||||
int iid = gl_InvocationID;
|
||||
|
||||
gl_out[gl_InvocationID].gl_Position = p;
|
||||
gl_out[gl_InvocationID].gl_PointSize = ps; // ERROR, need point_size extension
|
||||
gl_out[gl_InvocationID].gl_ClipDistance[1] = cd; // ERROR, not in ES
|
||||
|
||||
gl_TessLevelOuter[3] = 3.2;
|
||||
gl_TessLevelInner[1] = 1.3;
|
||||
|
||||
if (a > 10)
|
||||
barrier(); // ERROR
|
||||
else
|
||||
barrier(); // ERROR
|
||||
|
||||
barrier();
|
||||
|
||||
do {
|
||||
barrier(); // ERROR
|
||||
} while (a > 10);
|
||||
|
||||
switch (a) {
|
||||
default:
|
||||
barrier(); // ERROR
|
||||
break;
|
||||
}
|
||||
a < 12 ? a : (barrier(), a); // ERROR
|
||||
{
|
||||
barrier();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
barrier(); // ERROR
|
||||
}
|
||||
|
||||
layout(vertices = 4) in; // ERROR, not on in
|
||||
layout(vertices = 5) out; // ERROR, changing #
|
||||
|
||||
void foo()
|
||||
{
|
||||
gl_out[4].gl_Position; // ERROR, out of range
|
||||
|
||||
barrier(); // ERROR, not in main
|
||||
}
|
||||
|
||||
in vec2 ina; // ERROR, not array
|
||||
in vec2 inb[];
|
||||
in vec2 inc[18]; // ERROR, wrong size
|
||||
in vec2 ind[gl_MaxPatchVertices];
|
||||
patch out float implA[]; // ERROR, not sized
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
layout(location = 3) in vec4 ivla[];
|
||||
layout(location = 4) in vec4 ivlb[];
|
||||
layout(location = 4) in vec4 ivlc[]; // ERROR, overlapping
|
||||
|
||||
layout(location = 3) out vec4 ovla[];
|
||||
layout(location = 4) out vec4 ovlb[];
|
||||
layout(location = 4) out vec4 ovlc[]; // ERROR, overlapping
|
||||
|
||||
void foop()
|
||||
{
|
||||
precise float d; // ERROR without gpu_shader5
|
||||
d = fma(d, d, d); // ERROR without gpu_shader5
|
||||
}
|
||||
|
||||
patch out pinbn {
|
||||
int a;
|
||||
} pinbi;
|
||||
|
||||
centroid out vec3 myColor2[];
|
||||
centroid in vec3 centr[];
|
||||
sample out vec4 perSampleColor[]; // ERROR without sample extensions
|
||||
|
||||
layout(vertices = 4) out float badlay[]; // ERROR, not on a variable
|
||||
out float misSized[5]; // ERROR, size doesn't match
|
||||
out float okaySize[4];
|
||||
|
||||
#extension GL_OES_tessellation_point_size : enable
|
||||
|
||||
void pointSize2()
|
||||
{
|
||||
float ps = gl_in[1].gl_PointSize;
|
||||
gl_out[gl_InvocationID].gl_PointSize = ps;
|
||||
}
|
||||
|
||||
#extension GL_OES_gpu_shader5 : enable
|
||||
|
||||
precise vec3 pv3;
|
||||
|
||||
void goodfoop()
|
||||
{
|
||||
precise float d;
|
||||
|
||||
pv3 *= pv3;
|
||||
pv3 = fma(pv3, pv3, pv3);
|
||||
d = fma(d, d, d);
|
||||
}
|
||||
|
||||
void bbextBad()
|
||||
{
|
||||
gl_BoundingBoxEXT; // ERROR without GL_EXT_primitive_bounding_box
|
||||
gl_BoundingBox; // ERROR, version < 320
|
||||
}
|
||||
|
||||
#extension GL_EXT_primitive_bounding_box : enable
|
||||
|
||||
void bbext()
|
||||
{
|
||||
gl_BoundingBoxEXT[0] = vec4(0.0);
|
||||
gl_BoundingBoxEXT[1] = vec4(1.0);
|
||||
gl_BoundingBoxEXT[2] = vec4(2.0); // ERROR, overflow
|
||||
}
|
||||
|
||||
void bbBad()
|
||||
{
|
||||
gl_BoundingBoxOES; // ERROR without GL_OES_primitive_bounding_box
|
||||
}
|
||||
|
||||
#extension GL_OES_primitive_bounding_box : enable
|
||||
|
||||
void bb()
|
||||
{
|
||||
gl_BoundingBoxOES[0] = vec4(0.0);
|
||||
gl_BoundingBoxOES[1] = vec4(1.0);
|
||||
gl_BoundingBoxOES[2] = vec4(2.0); // ERROR, overflow
|
||||
}
|
||||
|
||||
out patch badpatchBName { // ERROR, array size required
|
||||
float f;
|
||||
} badpatchIName[];
|
||||
|
||||
out patch patchBName {
|
||||
float f;
|
||||
} patchIName[4];
|
||||
|
||||
void outputtingOutparam(out int a)
|
||||
{
|
||||
a = 2;
|
||||
}
|
||||
|
||||
void outputting()
|
||||
{
|
||||
outa[gl_InvocationID] = 2;
|
||||
outa[1] = 2; // ERROR, not gl_InvocationID
|
||||
gl_out[0].gl_Position = vec4(1.0); // ERROR, not gl_InvocationID
|
||||
outa[1];
|
||||
gl_out[0];
|
||||
outputtingOutparam(outa[0]); // ERROR, not gl_InvocationID
|
||||
outputtingOutparam(outa[gl_InvocationID]);
|
||||
patchIName[1].f = 3.14;
|
||||
outa[(gl_InvocationID)] = 2;
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
#version 310 es
|
||||
|
||||
#extension GL_EXT_tessellation_shader : enable
|
||||
#extension GL_OES_tessellation_shader : enable
|
||||
#extension GL_EXT_tessellation_shader : disable
|
||||
|
||||
layout(vertices = 4) out; // ERROR
|
||||
layout(quads, cw) in;
|
||||
layout(triangles) in; // ERROR
|
||||
layout(isolines) in; // ERROR
|
||||
|
||||
layout(ccw) in; // ERROR
|
||||
layout(cw) in;
|
||||
|
||||
layout(fractional_odd_spacing) in;
|
||||
layout(equal_spacing) in; // ERROR
|
||||
layout(fractional_even_spacing) in; // ERROR
|
||||
|
||||
layout(point_mode) in;
|
||||
|
||||
patch in vec4 patchIn;
|
||||
patch out vec4 patchOut; // ERROR
|
||||
|
||||
void main()
|
||||
{
|
||||
barrier(); // ERROR
|
||||
|
||||
int a = gl_MaxTessEvaluationInputComponents +
|
||||
gl_MaxTessEvaluationOutputComponents +
|
||||
gl_MaxTessEvaluationTextureImageUnits +
|
||||
gl_MaxTessEvaluationUniformComponents +
|
||||
gl_MaxTessPatchComponents +
|
||||
gl_MaxPatchVertices +
|
||||
gl_MaxTessGenLevel;
|
||||
|
||||
vec4 p = gl_in[1].gl_Position;
|
||||
float ps = gl_in[1].gl_PointSize; // ERROR, need point_size extension
|
||||
float cd = gl_in[1].gl_ClipDistance[2]; // ERROR, not in ES
|
||||
|
||||
int pvi = gl_PatchVerticesIn;
|
||||
int pid = gl_PrimitiveID;
|
||||
vec3 tc = gl_TessCoord;
|
||||
float tlo = gl_TessLevelOuter[3];
|
||||
float tli = gl_TessLevelInner[1];
|
||||
|
||||
gl_Position = p;
|
||||
gl_PointSize = ps; // ERROR, need point_size extension
|
||||
gl_ClipDistance[2] = cd; // ERROR, not in ES
|
||||
}
|
||||
|
||||
smooth patch in vec4 badp1; // ERROR
|
||||
flat patch in vec4 badp2; // ERROR
|
||||
noperspective patch in vec4 badp3; // ERROR
|
||||
patch sample in vec3 badp4; // ERROR
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
|
||||
in gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
} gl_in[];
|
||||
|
||||
in gl_PerVertex // ERROR, second redeclaration of gl_in
|
||||
{
|
||||
vec4 gl_Position;
|
||||
} gl_in[];
|
||||
|
||||
layout(quads, cw) out; // ERROR
|
||||
layout(triangles) out; // ERROR
|
||||
layout(isolines) out; // ERROR
|
||||
layout(cw) out; // ERROR
|
||||
layout(fractional_odd_spacing) out; // ERROR
|
||||
layout(equal_spacing) out; // ERROR
|
||||
layout(fractional_even_spacing) out; // ERROR
|
||||
layout(point_mode) out; // ERROR
|
||||
|
||||
in vec2 ina; // ERROR, not array
|
||||
in vec2 inb[];
|
||||
in vec2 inc[18]; // ERROR, wrong size
|
||||
in vec2 ind[gl_MaxPatchVertices];
|
||||
|
||||
in testbla { // ERROR, not array
|
||||
int f;
|
||||
} bla;
|
||||
|
||||
in testblb {
|
||||
int f;
|
||||
} blb[];
|
||||
|
||||
in testblc { // ERROR wrong size
|
||||
int f;
|
||||
} blc[18];
|
||||
|
||||
in testbld {
|
||||
int f;
|
||||
} bld[gl_MaxPatchVertices];
|
||||
|
||||
layout(location = 23) in vec4 ivla[];
|
||||
layout(location = 24) in vec4 ivlb[];
|
||||
layout(location = 24) in vec4 ivlc[]; // ERROR, overlap
|
||||
|
||||
layout(location = 23) out vec4 ovla[2];
|
||||
layout(location = 24) out vec4 ovlb[2]; // ERROR, overlap
|
||||
|
||||
in float gl_TessLevelOuter[4]; // ERROR, can't redeclare
|
||||
|
||||
patch in pinbn {
|
||||
int a;
|
||||
} pinbi;
|
||||
|
||||
centroid out vec3 myColor2;
|
||||
centroid in vec3 centr[];
|
||||
sample out vec4 perSampleColor; // ERROR without sample extensions
|
||||
|
||||
#extension GL_OES_tessellation_point_size : enable
|
||||
|
||||
void pointSize2()
|
||||
{
|
||||
float ps = gl_in[1].gl_PointSize; // ERROR, not in the redeclaration, but no error on use of gl_PointSize
|
||||
gl_PointSize = ps;
|
||||
}
|
||||
|
||||
#extension GL_EXT_primitive_bounding_box : enable
|
||||
|
||||
void bbbad()
|
||||
{
|
||||
gl_BoundingBoxOES; // ERROR, wrong stage
|
||||
}
|
|
@ -1,403 +0,0 @@
|
|||
#version 310 es
|
||||
|
||||
shared vec4 s; // ERROR
|
||||
layout(local_size_x = 2) out; // ERROR
|
||||
buffer vec4 v; // ERROR
|
||||
in int ini;
|
||||
layout(location = 2) uniform mat4 x;
|
||||
layout(location = 3) uniform mat4 y;
|
||||
layout(location = 2) out mat4 xi;
|
||||
layout(location = 3) out mat4 yi; // ERROR, locations conflict with xi
|
||||
|
||||
void main()
|
||||
{
|
||||
uvec2 u2;
|
||||
u2 = uaddCarry(u2, u2, u2);
|
||||
uint u1;
|
||||
u1 = usubBorrow(u1, u1, u1);
|
||||
uvec4 u4;
|
||||
umulExtended(u4, u4, u4, u4);
|
||||
ivec4 i4;
|
||||
imulExtended(i4, i4, i4, i4);
|
||||
int i1;
|
||||
i1 = bitfieldExtract(i1, 4, 5);
|
||||
uvec3 u3;
|
||||
u3 = bitfieldExtract(u3, 4, 5);
|
||||
ivec3 i3;
|
||||
i3 = bitfieldInsert(i3, i3, 4, 5);
|
||||
u1 = bitfieldInsert(u1, u1, 4, 5);
|
||||
ivec2 i2;
|
||||
i2 = bitfieldReverse(i2);
|
||||
u4 = bitfieldReverse(u4);
|
||||
i1 = bitCount(i1);
|
||||
i3 = bitCount(u3);
|
||||
i2 = findLSB(i2);
|
||||
i4 = findLSB(u4);
|
||||
i1 = findMSB(i1);
|
||||
i2 = findMSB(u2);
|
||||
|
||||
vec3 v3;
|
||||
v3 = frexp(v3, i3);
|
||||
vec2 v2;
|
||||
v2 = ldexp(v2, i2);
|
||||
|
||||
mediump vec4 v4;
|
||||
u1 = packUnorm4x8(v4);
|
||||
u1 = packSnorm4x8(v4);
|
||||
v4 = unpackUnorm4x8(u1);
|
||||
v4 = unpackSnorm4x8(u1);
|
||||
}
|
||||
|
||||
precision highp sampler2DMS;
|
||||
precision highp isampler2DMS;
|
||||
precision highp usampler2DMS;
|
||||
|
||||
uniform sampler2DMS s2dms;
|
||||
uniform isampler2DMS is2dms;
|
||||
uniform usampler2DMS us2dms;
|
||||
uniform usampler2DMSArray us2dmsa; // ERROR
|
||||
|
||||
void foo()
|
||||
{
|
||||
ivec2 v2;
|
||||
v2 = textureSize(s2dms);
|
||||
v2 = textureSize(us2dms);
|
||||
vec4 v4 = texelFetch(s2dms, v2, 2);
|
||||
ivec4 iv4 = texelFetch(is2dms, v2, 2);
|
||||
textureSamples(s2dms); // ERROR
|
||||
float f;
|
||||
frexp(f, ini); // ERROR, i not writable
|
||||
}
|
||||
|
||||
out bool outb; // ERROR
|
||||
out sampler2D outo; // ERROR
|
||||
out float outa[4];
|
||||
out float outaa[4][2]; // ERROR
|
||||
struct S { float f; };
|
||||
out S outs;
|
||||
out S[4] outasa; // ERROR
|
||||
out S outsa[4]; // ERROR
|
||||
struct SA { float f[4]; };
|
||||
out SA outSA; // ERROR
|
||||
struct SS { float f; S s; };
|
||||
out SS outSS; // ERROR
|
||||
|
||||
layout(std430) uniform U430 { int a; } U430i; // ERROR
|
||||
layout(std430) buffer B430 { int a; } B430i;
|
||||
|
||||
#ifndef GL_OES_shader_io_blocks
|
||||
#error GL_OES_shader_io_blocks not defined
|
||||
#endif
|
||||
|
||||
#extension GL_OES_shader_io_blocks : enable
|
||||
|
||||
out outbname {
|
||||
int a;
|
||||
out vec4 v;
|
||||
highp sampler2D s; // ERROR, opaque type
|
||||
} outbinst;
|
||||
|
||||
out outbname2 {
|
||||
layout(location = 12) int aAnon;
|
||||
layout(location = 13) vec4 vAnon;
|
||||
};
|
||||
|
||||
layout(location = 12) out highp int aliased; // ERROR, aliasing location
|
||||
|
||||
in inbname { int a; } inbinst; // ERROR, no in block in vertex shader
|
||||
|
||||
out gl_PerVertex { // ERROR, has extra member
|
||||
highp vec4 gl_Position;
|
||||
highp vec4 t;
|
||||
};
|
||||
|
||||
void foo_IO()
|
||||
{
|
||||
int sum = gl_VertexID +
|
||||
gl_InstanceID;
|
||||
gl_Position = vec4(1.0);
|
||||
gl_PointSize = 2.0; // ERROR, removed by redeclaration
|
||||
}
|
||||
|
||||
out gl_PerVertex { // ERROR, already used and already redeclared
|
||||
highp vec4 gl_Position;
|
||||
highp vec4 t;
|
||||
};
|
||||
|
||||
smooth out smo { // ERROR, no smooth on a block
|
||||
int i;
|
||||
} smon;
|
||||
|
||||
flat out fmo { // ERROR, no flat on a block
|
||||
int i;
|
||||
} fmon;
|
||||
|
||||
centroid out cmo { // ERROR, no centroid on a block
|
||||
int i;
|
||||
} cmon;
|
||||
|
||||
invariant out imo { // ERROR, no invariant on a block
|
||||
int i;
|
||||
} imon;
|
||||
|
||||
in vec2 inf, ing;
|
||||
uniform ivec2 offsets[4];
|
||||
uniform sampler2D sArray[4];
|
||||
uniform int sIndex;
|
||||
layout(binding = 0) uniform atomic_uint auArray[2];
|
||||
uniform ubName { int i; } ubInst[4];
|
||||
buffer bbName { int i; } bbInst[4];
|
||||
highp uniform writeonly image2D iArray[5];
|
||||
const ivec2 constOffsets[4] = ivec2[4](ivec2(0.1), ivec2(0.2), ivec2(0.3), ivec2(0.4));
|
||||
|
||||
void pfooBad()
|
||||
{
|
||||
precise vec2 h; // ERROR reserved
|
||||
h = fma(inf, ing, h); // ERROR, not available
|
||||
sArray[sIndex + 1]; // ERRRO, not supported
|
||||
auArray[sIndex + 1];
|
||||
ubInst[1];
|
||||
bbInst[2];
|
||||
ubInst[sIndex + 1]; // ERROR, not supported
|
||||
bbInst[sIndex]; // ERROR, not supported
|
||||
iArray[2];
|
||||
iArray[sIndex * 2]; // ERROR, not supported
|
||||
textureGatherOffset(sArray[0], vec2(0.1), ivec2(inf)); // ERROR, offset not constant
|
||||
textureGatherOffsets(sArray[0], vec2(0.1), constOffsets); // ERROR, not available
|
||||
}
|
||||
|
||||
#extension GL_OES_gpu_shader5 : enable
|
||||
|
||||
void pfoo()
|
||||
{
|
||||
precise vec2 h;
|
||||
h = fma(inf, ing, h);
|
||||
sArray[sIndex + 1];
|
||||
ubInst[sIndex + 1];
|
||||
bbInst[sIndex - 2]; // ERROR, still not supported
|
||||
iArray[2];
|
||||
iArray[sIndex - 2];
|
||||
textureGatherOffset(sArray[0], vec2(0.1), ivec2(inf));
|
||||
textureGatherOffsets(sArray[0], vec2(0.1), constOffsets);
|
||||
textureGatherOffsets(sArray[0], vec2(0.1), offsets); // ERROR, offset not constant
|
||||
}
|
||||
|
||||
uniform samplerBuffer badSamp1; // ERROR, reserved
|
||||
uniform isamplerBuffer badSamp2; // ERROR, reserved
|
||||
uniform usamplerBuffer badSamp3; // ERROR, reserved
|
||||
uniform writeonly imageBuffer badSamp4; // ERROR, reserved
|
||||
uniform writeonly iimageBuffer badSamp5; // ERROR, reserved
|
||||
uniform writeonly uimageBuffer badSamp6; // ERROR, reserved
|
||||
|
||||
#extension GL_OES_texture_buffer : enable
|
||||
#extension GL_EXT_texture_buffer : enable
|
||||
|
||||
uniform samplerBuffer noPreSamp1; // ERROR, no default precision
|
||||
uniform isamplerBuffer noPreSamp2; // ERROR, no default precision
|
||||
uniform usamplerBuffer noPreSamp3; // ERROR, no default precision
|
||||
uniform writeonly imageBuffer noPreSamp4; // ERROR, no default precision
|
||||
uniform writeonly iimageBuffer noPreSamp5; // ERROR, no default precision
|
||||
uniform writeonly uimageBuffer noPreSamp6; // ERROR, no default precision
|
||||
|
||||
precision highp samplerBuffer;
|
||||
precision highp isamplerBuffer;
|
||||
precision highp usamplerBuffer;
|
||||
precision highp imageBuffer;
|
||||
precision highp iimageBuffer;
|
||||
precision highp uimageBuffer;
|
||||
|
||||
#ifdef GL_OES_texture_buffer
|
||||
uniform samplerBuffer bufSamp1;
|
||||
uniform isamplerBuffer bufSamp2;
|
||||
uniform usamplerBuffer bufSamp3;
|
||||
#endif
|
||||
#ifdef GL_EXT_texture_buffer
|
||||
uniform writeonly imageBuffer bufSamp4;
|
||||
uniform writeonly iimageBuffer bufSamp5;
|
||||
uniform writeonly uimageBuffer bufSamp6;
|
||||
#endif
|
||||
|
||||
void bufferT()
|
||||
{
|
||||
highp int s1 = textureSize(bufSamp1);
|
||||
highp int s2 = textureSize(bufSamp2);
|
||||
highp int s3 = textureSize(bufSamp3);
|
||||
|
||||
highp int s4 = imageSize(bufSamp4);
|
||||
highp int s5 = imageSize(bufSamp5);
|
||||
highp int s6 = imageSize(bufSamp6);
|
||||
|
||||
highp vec4 f1 = texelFetch(bufSamp1, s1);
|
||||
highp ivec4 f2 = texelFetch(bufSamp2, s2);
|
||||
highp uvec4 f3 = texelFetch(bufSamp3, s3);
|
||||
}
|
||||
|
||||
uniform writeonly imageCubeArray badCA1; // ERROR, reserved
|
||||
uniform writeonly iimageCubeArray badCA2; // ERROR, reserved
|
||||
uniform writeonly uimageCubeArray badCA3; // ERROR, reserved
|
||||
|
||||
uniform samplerCubeArray badCA4; // ERROR, reserved
|
||||
uniform samplerCubeArrayShadow badCA5; // ERROR, reserved
|
||||
uniform isamplerCubeArray badCA6; // ERROR, reserved
|
||||
uniform usamplerCubeArray badCA7; // ERROR, reserved
|
||||
|
||||
#extension GL_OES_texture_cube_map_array : enable
|
||||
|
||||
uniform writeonly imageCubeArray noPreCA1; // ERROR, no default precision
|
||||
uniform writeonly iimageCubeArray noPreCA2; // ERROR, no default precision
|
||||
uniform writeonly uimageCubeArray noPreCA3; // ERROR, no default precision
|
||||
|
||||
uniform samplerCubeArray noPreCA4; // ERROR, no default precision
|
||||
uniform samplerCubeArrayShadow noPreCA5; // ERROR, no default precision
|
||||
uniform isamplerCubeArray noPreCA6; // ERROR, no default precision
|
||||
uniform usamplerCubeArray noPreCA7; // ERROR, no default precision
|
||||
|
||||
precision highp imageCubeArray ;
|
||||
precision highp iimageCubeArray ;
|
||||
precision highp uimageCubeArray ;
|
||||
|
||||
precision highp samplerCubeArray ;
|
||||
precision highp samplerCubeArrayShadow;
|
||||
precision highp isamplerCubeArray ;
|
||||
precision highp usamplerCubeArray ;
|
||||
|
||||
uniform writeonly imageCubeArray CA1;
|
||||
uniform writeonly iimageCubeArray CA2;
|
||||
uniform writeonly uimageCubeArray CA3;
|
||||
|
||||
layout(rgba16f) uniform readonly imageCubeArray rCA1;
|
||||
layout(rgba32i) uniform readonly iimageCubeArray rCA2;
|
||||
layout(r32ui) uniform readonly uimageCubeArray rCA3;
|
||||
|
||||
#ifdef GL_OES_texture_cube_map_array
|
||||
uniform samplerCubeArray CA4;
|
||||
uniform samplerCubeArrayShadow CA5;
|
||||
uniform isamplerCubeArray CA6;
|
||||
uniform usamplerCubeArray CA7;
|
||||
#endif
|
||||
|
||||
void CAT()
|
||||
{
|
||||
highp ivec3 s4 = textureSize(CA4, 1);
|
||||
highp ivec3 s5 = textureSize(CA5, 1);
|
||||
highp ivec3 s6 = textureSize(CA6, 1);
|
||||
highp ivec3 s7 = textureSize(CA7, 1);
|
||||
|
||||
highp vec4 t4 = texture(CA4, vec4(0.5));
|
||||
highp float t5 = texture(CA5, vec4(0.5), 3.0);
|
||||
highp ivec4 t6 = texture(CA6, vec4(0.5));
|
||||
highp uvec4 t7 = texture(CA7, vec4(0.5));
|
||||
|
||||
highp vec4 L4 = textureLod(CA4, vec4(0.5), 0.24);
|
||||
highp ivec4 L6 = textureLod(CA6, vec4(0.5), 0.26);
|
||||
highp uvec4 L7 = textureLod(CA7, vec4(0.5), 0.27);
|
||||
|
||||
highp vec4 g4 = textureGrad(CA4, vec4(0.5), vec3(0.1), vec3(0.2));
|
||||
highp ivec4 g6 = textureGrad(CA6, vec4(0.5), vec3(0.1), vec3(0.2));
|
||||
highp uvec4 g7 = textureGrad(CA7, vec4(0.5), vec3(0.1), vec3(0.2));
|
||||
|
||||
highp vec4 gath4 = textureGather(CA4, vec4(0.5));
|
||||
highp vec4 gathC4 = textureGather(CA4, vec4(0.5), 2);
|
||||
highp ivec4 gath6 = textureGather(CA6, vec4(0.5));
|
||||
highp ivec4 gathC6 = textureGather(CA6, vec4(0.5), 1);
|
||||
highp uvec4 gath7 = textureGather(CA7, vec4(0.5));
|
||||
highp uvec4 gathC7 = textureGather(CA7, vec4(0.5), 0);
|
||||
|
||||
highp vec4 gath5 = textureGather(CA5, vec4(0.5), 2.5);
|
||||
|
||||
highp ivec3 s1 = imageSize(CA1);
|
||||
highp ivec3 s2 = imageSize(CA2);
|
||||
highp ivec3 s3 = imageSize(CA3);
|
||||
|
||||
imageStore(CA1, s3, vec4(1));
|
||||
imageStore(CA2, s3, ivec4(1));
|
||||
imageStore(CA3, s3, uvec4(1));
|
||||
|
||||
highp vec4 cl1 = imageLoad(rCA1, s3);
|
||||
highp ivec4 cl2 = imageLoad(rCA2, s3);
|
||||
highp uvec4 cl3 = imageLoad(rCA3, s3);
|
||||
}
|
||||
|
||||
uniform sampler2DMSArray bad2DMS; // ERROR, reserved
|
||||
uniform isampler2DMSArray bad2DMSi; // ERROR, reserved
|
||||
uniform usampler2DMSArray bad2DMSu; // ERROR, reserved
|
||||
|
||||
#extension GL_OES_texture_storage_multisample_2d_array : enable
|
||||
|
||||
#ifdef GL_OES_texture_storage_multisample_2d_array
|
||||
|
||||
uniform sampler2DMSArray noPrec2DMS; // ERROR, no default
|
||||
uniform isampler2DMSArray noPrec2DMSi; // ERROR, no default
|
||||
uniform usampler2DMSArray noPrec2DMSu; // ERROR, no default
|
||||
|
||||
#endif
|
||||
|
||||
precision highp sampler2DMSArray;
|
||||
precision highp isampler2DMSArray;
|
||||
precision highp usampler2DMSArray;
|
||||
|
||||
uniform sampler2DMSArray samp2DMSA;
|
||||
uniform isampler2DMSArray samp2DMSAi;
|
||||
uniform usampler2DMSArray samp2DMSAu;
|
||||
|
||||
void MSA()
|
||||
{
|
||||
vec4 tf = texelFetch(samp2DMSA, ivec3(5), 2);
|
||||
ivec4 tfi = texelFetch(samp2DMSAi, ivec3(5), 2);
|
||||
uvec4 tfu = texelFetch(samp2DMSAu, ivec3(5), 2);
|
||||
|
||||
ivec3 tfs = textureSize(samp2DMSA);
|
||||
ivec3 tfsi = textureSize(samp2DMSAi);
|
||||
ivec3 tfsb = textureSize(samp2DMSAi, 4); // ERROR, no lod
|
||||
ivec3 tfsu = textureSize(samp2DMSAu);
|
||||
}
|
||||
|
||||
#ifdef GL_OES_shader_image_atomic
|
||||
#extension GL_OES_shader_image_atomic : enable
|
||||
#endif
|
||||
|
||||
uniform layout(r32f) highp image2D im2Df;
|
||||
uniform layout(r32ui) highp uimage2D im2Du;
|
||||
uniform layout(r32i) highp iimage2D im2Di;
|
||||
uniform ivec2 P;
|
||||
|
||||
void goodImageAtom()
|
||||
{
|
||||
float datf;
|
||||
int dati;
|
||||
uint datu;
|
||||
|
||||
imageAtomicAdd( im2Di, P, dati);
|
||||
imageAtomicAdd( im2Du, P, datu);
|
||||
imageAtomicMin( im2Di, P, dati);
|
||||
imageAtomicMin( im2Du, P, datu);
|
||||
imageAtomicMax( im2Di, P, dati);
|
||||
imageAtomicMax( im2Du, P, datu);
|
||||
imageAtomicAnd( im2Di, P, dati);
|
||||
imageAtomicAnd( im2Du, P, datu);
|
||||
imageAtomicOr( im2Di, P, dati);
|
||||
imageAtomicOr( im2Du, P, datu);
|
||||
imageAtomicXor( im2Di, P, dati);
|
||||
imageAtomicXor( im2Du, P, datu);
|
||||
imageAtomicExchange(im2Di, P, dati);
|
||||
imageAtomicExchange(im2Du, P, datu);
|
||||
imageAtomicExchange(im2Df, P, datf);
|
||||
imageAtomicCompSwap(im2Di, P, 3, dati);
|
||||
imageAtomicCompSwap(im2Du, P, 5u, datu);
|
||||
}
|
||||
|
||||
sample out vec4 colorSampInBad; // ERROR, reserved
|
||||
|
||||
#extension GL_OES_shader_multisample_interpolation : enable
|
||||
|
||||
sample out vec4 colorSample;
|
||||
flat sample out vec4 colorfsi;
|
||||
sample out vec3 sampInArray[4];
|
||||
in vec4 inv4;
|
||||
|
||||
void badInterp()
|
||||
{
|
||||
interpolateAtCentroid(inv4); // ERROR, wrong stage
|
||||
interpolateAtSample(inv4, 1); // ERROR, need extension
|
||||
interpolateAtOffset(inv4, vec2(0.2)); // ERROR, need extension
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
#version 310 es
|
||||
|
||||
// Check name mangling of functions with parameters that are multi-dimensional arrays.
|
||||
|
||||
#define NX 2
|
||||
#define NY 3
|
||||
#define NZ 4
|
||||
void f(bool a, float b, uint[4] c, int[NY][NX] d) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
int[NY][NX] d;
|
||||
f(false, 12.1, uint[NZ](uint(0),uint(1),uint(1),uint(2)), d);
|
||||
}
|
||||
|
||||
buffer b {
|
||||
float u[]; // ERROR
|
||||
vec4 v[];
|
||||
} name[3];
|
||||
|
||||
uniform ub {
|
||||
float u;
|
||||
vec4 v[]; // ERROR
|
||||
} uname[3];
|
||||
|
||||
buffer b2 {
|
||||
float u;
|
||||
vec4 v[][]; // ERROR
|
||||
} name2[3];
|
||||
|
||||
buffer b3 {
|
||||
float u;
|
||||
vec4 v[][7];
|
||||
} name3[3];
|
||||
|
||||
// General arrays of arrays
|
||||
|
||||
float[4][5][6] many[1][2][3];
|
||||
|
||||
float gu[][7]; // ERROR, size required
|
||||
float g4[4][7];
|
||||
float g5[5][7];
|
||||
|
||||
float[4][7] foo(float a[5][7])
|
||||
{
|
||||
float r[7];
|
||||
r = a[2];
|
||||
float[](a[0], a[1], r, a[3]); // ERROR, too few dims
|
||||
float[4][7][4](a[0], a[1], r, a[3]); // ERROR, too many dims
|
||||
return float[4][7](a[0], a[1], r, a[3]);
|
||||
return float[][](a[0], a[1], r, a[3]);
|
||||
return float[][7](a[0], a[1], a[2], a[3]);
|
||||
}
|
||||
|
||||
void bar(float[5][7]) {}
|
||||
|
||||
void foo2()
|
||||
{
|
||||
{
|
||||
float gu[3][4][2];
|
||||
|
||||
gu[2][4][1] = 4.0; // ERROR, overflow
|
||||
}
|
||||
vec4 ca4[3][2] = vec4[][](vec4[2](vec4(0.0), vec4(1.0)),
|
||||
vec4[2](vec4(0.0), vec4(1.0)),
|
||||
vec4[2](vec4(0.0), vec4(1.0)));
|
||||
vec4 caim[][2] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)),
|
||||
vec4[2](vec4(4.0), vec4(2.0)),
|
||||
vec4[2](vec4(4.0), vec4(2.0)));
|
||||
vec4 caim2[][] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)),
|
||||
vec4[2](vec4(4.0), vec4(2.0)),
|
||||
vec4[2](vec4(4.0), vec4(2.0)));
|
||||
vec4 caim3[3][] = vec4[][](vec4[2](vec4(4.0), vec4(2.0)),
|
||||
vec4[2](vec4(4.0), vec4(2.0)),
|
||||
vec4[2](vec4(4.0), vec4(2.0)));
|
||||
|
||||
g4 = foo(g5);
|
||||
g5 = g4; // ERROR, wrong types
|
||||
gu = g4; // ERROR, not yet sized
|
||||
|
||||
foo(gu); // ERROR, not yet sized
|
||||
bar(g5);
|
||||
|
||||
if (foo(g5) == g4)
|
||||
;
|
||||
if (foo(g5) == g5) // ERROR, different types
|
||||
;
|
||||
|
||||
float u[5][7];
|
||||
u[5][2] = 5.0; // ERROR
|
||||
foo(u);
|
||||
|
||||
vec4 badAss[3];
|
||||
name[1].v[-1]; // ERROR
|
||||
name[1].v[1] = vec4(4.3);
|
||||
name[1].v = badAss; // ERROR, bad assignemnt
|
||||
|
||||
name3[0].v[1].length(); // 7
|
||||
name3[0].v.length(); // run time
|
||||
}
|
||||
|
||||
struct badS {
|
||||
int sa[]; // ERROR
|
||||
int a[][]; // ERROR
|
||||
int b[][2]; // ERROR
|
||||
int c[2][]; // ERROR
|
||||
int d[][4]; // ERROR
|
||||
};
|
||||
|
||||
in float inArray[2][3]; // ERROR
|
||||
out float outArray[2][3]; // ERROR
|
||||
|
||||
uniform ubaa {
|
||||
int a;
|
||||
} ubaaname[2][3]; // ERROR
|
||||
|
||||
vec3 func(in mat3[2] x[3])
|
||||
{
|
||||
mat3 a0 = x[2][1];
|
||||
return a0[2];
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#version 310 es
|
||||
layout (binding=0) uniform Block {
|
||||
highp int a[];
|
||||
} uni;
|
||||
layout (location=0) out highp int o;
|
||||
void main() {
|
||||
o = uni.a[2];
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue