Updated bgfx and bx
parent
39cd8bde19
commit
86f4b2d751
|
@ -31,3 +31,7 @@ indent_size = 4
|
||||||
[remotery/*]
|
[remotery/*]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
|
[glsl-optimizer/*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 3
|
||||||
|
|
|
@ -205,7 +205,7 @@ void ProcessAverages( v4i* a )
|
||||||
#ifdef __SSE4_1__
|
#ifdef __SSE4_1__
|
||||||
for( int i=0; i<2; i++ )
|
for( int i=0; i<2; i++ )
|
||||||
{
|
{
|
||||||
__m128i d = _mm_loadu_si128((__m128i*)a[i*2].data());
|
__m128i d = _mm_loadu_si128((__m128i*)a[i*2]);
|
||||||
|
|
||||||
__m128i t = _mm_add_epi16(_mm_mullo_epi16(d, _mm_set1_epi16(31)), _mm_set1_epi16(128));
|
__m128i t = _mm_add_epi16(_mm_mullo_epi16(d, _mm_set1_epi16(31)), _mm_set1_epi16(128));
|
||||||
|
|
||||||
|
@ -222,19 +222,19 @@ void ProcessAverages( v4i* a )
|
||||||
|
|
||||||
__m128i a0 = _mm_or_si128(_mm_slli_epi16(c, 3), _mm_srli_epi16(c, 2));
|
__m128i a0 = _mm_or_si128(_mm_slli_epi16(c, 3), _mm_srli_epi16(c, 2));
|
||||||
|
|
||||||
_mm_storeu_si128((__m128i*)a[4+i*2].data(), a0);
|
_mm_storeu_si128((__m128i*)a[4+i*2], a0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int i=0; i<2; i++ )
|
for( int i=0; i<2; i++ )
|
||||||
{
|
{
|
||||||
__m128i d = _mm_loadu_si128((__m128i*)a[i*2].data());
|
__m128i d = _mm_loadu_si128((__m128i*)a[i*2]);
|
||||||
|
|
||||||
__m128i t0 = _mm_add_epi16(_mm_mullo_epi16(d, _mm_set1_epi16(15)), _mm_set1_epi16(128));
|
__m128i t0 = _mm_add_epi16(_mm_mullo_epi16(d, _mm_set1_epi16(15)), _mm_set1_epi16(128));
|
||||||
__m128i t1 = _mm_srli_epi16(_mm_add_epi16(t0, _mm_srli_epi16(t0, 8)), 8);
|
__m128i t1 = _mm_srli_epi16(_mm_add_epi16(t0, _mm_srli_epi16(t0, 8)), 8);
|
||||||
|
|
||||||
__m128i t2 = _mm_or_si128(t1, _mm_slli_epi16(t1, 4));
|
__m128i t2 = _mm_or_si128(t1, _mm_slli_epi16(t1, 4));
|
||||||
|
|
||||||
_mm_storeu_si128((__m128i*)a[i*2].data(), t2);
|
_mm_storeu_si128((__m128i*)a[i*2], t2);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for( int i=0; i<2; i++ )
|
for( int i=0; i<2; i++ )
|
||||||
|
|
|
@ -135,7 +135,7 @@ namespace Forsyth
|
||||||
|
|
||||||
float FindVertexScore(uint numActiveFaces, uint cachePosition, uint vertexCacheSize)
|
float FindVertexScore(uint numActiveFaces, uint cachePosition, uint vertexCacheSize)
|
||||||
{
|
{
|
||||||
assert(s_vertexScoresComputed);
|
assert(s_vertexScoresComputed); (void)s_vertexScoresComputed;
|
||||||
|
|
||||||
if ( numActiveFaces == 0 )
|
if ( numActiveFaces == 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -3045,6 +3045,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
|
||||||
/* Propagate precision qualifier for constant value */
|
/* Propagate precision qualifier for constant value */
|
||||||
if (type->qualifier.flags.q.constant) {
|
if (type->qualifier.flags.q.constant) {
|
||||||
ir_constant *constant_value = rhs->constant_expression_value();
|
ir_constant *constant_value = rhs->constant_expression_value();
|
||||||
|
if (NULL != constant_value) {
|
||||||
constant_value->set_precision((glsl_precision)type->qualifier.precision);
|
constant_value->set_precision((glsl_precision)type->qualifier.precision);
|
||||||
if (constant_value->type->is_array()) {
|
if (constant_value->type->is_array()) {
|
||||||
for (unsigned i = 0; i < constant_value->type->length; i++) {
|
for (unsigned i = 0; i < constant_value->type->length; i++) {
|
||||||
|
@ -3052,6 +3053,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate the constant value if this is a const or uniform
|
/* Calculate the constant value if this is a const or uniform
|
||||||
* declaration.
|
* declaration.
|
||||||
|
|
|
@ -280,6 +280,14 @@ static void propagate_precision_texture(ir_instruction *ir, void *data)
|
||||||
((precision_ctx*)data)->res = true;
|
((precision_ctx*)data)->res = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void propagate_precision_texture_metal(ir_instruction* ir, void* data)
|
||||||
|
{
|
||||||
|
// There are no precision specifiers in Metal
|
||||||
|
ir_texture* tex = ir->as_texture();
|
||||||
|
if (tex)
|
||||||
|
tex->set_precision(glsl_precision_undefined);
|
||||||
|
}
|
||||||
|
|
||||||
struct undefined_ass_ctx
|
struct undefined_ass_ctx
|
||||||
{
|
{
|
||||||
ir_variable* var;
|
ir_variable* var;
|
||||||
|
@ -386,7 +394,7 @@ static void propagate_precision_call(ir_instruction *ir, void *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool propagate_precision(exec_list* list, bool assign_high_to_undefined)
|
static bool propagate_precision(exec_list* list, bool metal_target)
|
||||||
{
|
{
|
||||||
bool anyProgress = false;
|
bool anyProgress = false;
|
||||||
precision_ctx ctx;
|
precision_ctx ctx;
|
||||||
|
@ -396,7 +404,11 @@ static bool propagate_precision(exec_list* list, bool assign_high_to_undefined)
|
||||||
ctx.root_ir = list;
|
ctx.root_ir = list;
|
||||||
foreach_in_list(ir_instruction, ir, list)
|
foreach_in_list(ir_instruction, ir, list)
|
||||||
{
|
{
|
||||||
|
if (metal_target)
|
||||||
|
visit_tree (ir, propagate_precision_texture_metal, &ctx);
|
||||||
|
else
|
||||||
visit_tree (ir, propagate_precision_texture, &ctx);
|
visit_tree (ir, propagate_precision_texture, &ctx);
|
||||||
|
|
||||||
visit_tree (ir, propagate_precision_deref, &ctx);
|
visit_tree (ir, propagate_precision_deref, &ctx);
|
||||||
bool hadProgress = ctx.res;
|
bool hadProgress = ctx.res;
|
||||||
ctx.res = false;
|
ctx.res = false;
|
||||||
|
@ -417,7 +429,7 @@ static bool propagate_precision(exec_list* list, bool assign_high_to_undefined)
|
||||||
anyProgress |= ctx.res;
|
anyProgress |= ctx.res;
|
||||||
|
|
||||||
// for globals that have undefined precision, set it to highp
|
// for globals that have undefined precision, set it to highp
|
||||||
if (assign_high_to_undefined)
|
if (metal_target)
|
||||||
{
|
{
|
||||||
foreach_in_list(ir_instruction, ir, list)
|
foreach_in_list(ir_instruction, ir, list)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1282,6 +1282,12 @@ void ir_print_metal_visitor::visit(ir_texture *ir)
|
||||||
sampler_uv_dim += 1;
|
sampler_uv_dim += 1;
|
||||||
const bool is_proj = (uv_dim > sampler_uv_dim) && !is_array;
|
const bool is_proj = (uv_dim > sampler_uv_dim) && !is_array;
|
||||||
|
|
||||||
|
// Construct as the expected return type of shadow2D as sample_compare returns a scalar
|
||||||
|
if (is_shadow)
|
||||||
|
{
|
||||||
|
buffer.asprintf_append("float4(");
|
||||||
|
}
|
||||||
|
|
||||||
// texture name & call to sample
|
// texture name & call to sample
|
||||||
ir->sampler->accept(this);
|
ir->sampler->accept(this);
|
||||||
if (is_shadow)
|
if (is_shadow)
|
||||||
|
@ -1345,6 +1351,12 @@ void ir_print_metal_visitor::visit(ir_texture *ir)
|
||||||
//@TODO: pixel offsets
|
//@TODO: pixel offsets
|
||||||
|
|
||||||
buffer.asprintf_append (")");
|
buffer.asprintf_append (")");
|
||||||
|
|
||||||
|
// Close float4 cast
|
||||||
|
if (is_shadow)
|
||||||
|
{
|
||||||
|
buffer.asprintf_append(")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Windows Build Configuration for AppVeyor
|
||||||
|
# http://www.appveyor.com/docs/appveyor-yml
|
||||||
|
|
||||||
|
# build version format
|
||||||
|
version: "{build}"
|
||||||
|
|
||||||
|
os: Visual Studio 2013
|
||||||
|
|
||||||
|
platform:
|
||||||
|
- Any CPU
|
||||||
|
|
||||||
|
configuration:
|
||||||
|
- Debug
|
||||||
|
- Release
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
clone_depth: 5
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true # Show final status immediately if a test fails.
|
||||||
|
|
||||||
|
# scripts that run after cloning repository
|
||||||
|
install:
|
||||||
|
- git clone https://github.com/google/googletest.git External/googletest
|
||||||
|
|
||||||
|
build:
|
||||||
|
parallel: true # enable MSBuild parallel builds
|
||||||
|
verbosity: minimal
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- mkdir build && cd build
|
||||||
|
- cmake .. -DCMAKE_INSTALL_PREFIX=install
|
||||||
|
- cmake --build . --config %CONFIGURATION% --target install
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- ctest -C %CONFIGURATION% --output-on-failure
|
||||||
|
- cd ../Test && bash runtests
|
|
@ -0,0 +1,12 @@
|
||||||
|
Language: Cpp
|
||||||
|
IndentWidth: 4
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping: { AfterFunction: true, AfterControlStatement: true }
|
||||||
|
IndentCaseLabels: false
|
||||||
|
ReflowComments: false
|
||||||
|
ColumnLimit: 120
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
|
@ -0,0 +1,17 @@
|
||||||
|
# test files have a mix of lf/crlf, and that's a good thing, for testing, don't mess with it
|
||||||
|
# bash scripts need lines ending with lf, and that's correct for Windows too, e.g., under Cygwin
|
||||||
|
# (scripts often don't have a suffix)
|
||||||
|
* -text
|
||||||
|
*.sh text eof=lf
|
||||||
|
|
||||||
|
# txt files should be native and normalized
|
||||||
|
*.txt text
|
||||||
|
|
||||||
|
# source code can be native and normalized, but simpler if lf everywhere; will try that way
|
||||||
|
*.h text eof=lf
|
||||||
|
*.c text eof=lf
|
||||||
|
*.cpp text eof=lf
|
||||||
|
*.y text eof=lf
|
||||||
|
*.out text eof=lf
|
||||||
|
*.conf text eof=lf
|
||||||
|
*.err text eof=lf
|
|
@ -0,0 +1,13 @@
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.exe
|
||||||
|
tags
|
||||||
|
TAGS
|
||||||
|
build/
|
||||||
|
Test/localResults/
|
||||||
|
Test/multiThread.out
|
||||||
|
Test/singleThread.out
|
||||||
|
Test/vert.spv
|
||||||
|
Test/frag.spv
|
||||||
|
External/googletest
|
|
@ -0,0 +1,60 @@
|
||||||
|
# Linux and Mac Build Configuration for Travis
|
||||||
|
|
||||||
|
language: cpp
|
||||||
|
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
|
|
||||||
|
# Use Ubuntu 14.04 LTS (Trusty) as the Linux testing environment.
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
|
||||||
|
env:
|
||||||
|
- 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
|
||||||
|
|
||||||
|
cache:
|
||||||
|
apt: true
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- clang-3.6
|
||||||
|
- ninja-build
|
||||||
|
|
||||||
|
install:
|
||||||
|
# Install ninja on Mac OS X.
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update && brew install ninja; fi
|
||||||
|
# Make sure that clang-3.6 is selected.
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "linux" && "$CC" == "clang" ]]; then
|
||||||
|
export CC=clang-3.6 CXX=clang++-3.6;
|
||||||
|
fi
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- git clone https://github.com/google/googletest.git External/googletest
|
||||||
|
|
||||||
|
script:
|
||||||
|
- mkdir build && cd build
|
||||||
|
# We need to install the compiled binaries so the paths in the runtests script can resolve correctly.
|
||||||
|
- cmake -GNinja -DCMAKE_BUILD_TYPE=${GLSLANG_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=`pwd`/install ..
|
||||||
|
- ninja install
|
||||||
|
# Run Google-Test-based tests.
|
||||||
|
- ctest --output-on-failure
|
||||||
|
# Run runtests-based tests.
|
||||||
|
- cd ../Test && ./runtests
|
|
@ -0,0 +1,77 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8.11)
|
||||||
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
option(ENABLE_AMD_EXTENSIONS "Enables support of AMD-specific extensions" ON)
|
||||||
|
option(ENABLE_GLSLANG_BINARIES "Builds glslangValidator and spirv-remap" ON)
|
||||||
|
|
||||||
|
option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON)
|
||||||
|
|
||||||
|
option(ENABLE_HLSL "Enables HLSL input support" ON)
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
set(CMAKE_INSTALL_PREFIX "install" CACHE STRING "prefix")
|
||||||
|
|
||||||
|
project(glslang)
|
||||||
|
|
||||||
|
if(ENABLE_AMD_EXTENSIONS)
|
||||||
|
add_definitions(-DAMD_EXTENSIONS)
|
||||||
|
endif(ENABLE_AMD_EXTENSIONS)
|
||||||
|
|
||||||
|
if(ENABLE_NV_EXTENSIONS)
|
||||||
|
add_definitions(-DNV_EXTENSIONS)
|
||||||
|
endif(ENABLE_NV_EXTENSIONS)
|
||||||
|
|
||||||
|
if(ENABLE_HLSL)
|
||||||
|
add_definitions(-DENABLE_HLSL)
|
||||||
|
endif(ENABLE_HLSL)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(CMAKE_DEBUG_POSTFIX "d")
|
||||||
|
if(MSVC)
|
||||||
|
include(ChooseMSVCCRT.cmake)
|
||||||
|
endif(MSVC)
|
||||||
|
add_definitions(-DGLSLANG_OSINCLUDE_WIN32)
|
||||||
|
elseif(UNIX)
|
||||||
|
add_definitions(-fPIC)
|
||||||
|
add_definitions(-DGLSLANG_OSINCLUDE_UNIX)
|
||||||
|
else(WIN32)
|
||||||
|
message("unknown platform")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
add_definitions(-Wall -Wmaybe-uninitialized -Wuninitialized -Wunused -Wunused-local-typedefs
|
||||||
|
-Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable)
|
||||||
|
add_definitions(-Wno-reorder) # disable this from -Wall, since it happens all over.
|
||||||
|
add_definitions(-std=c++11)
|
||||||
|
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||||
|
add_definitions(-Wall -Wuninitialized -Wunused -Wunused-local-typedefs
|
||||||
|
-Wunused-parameter -Wunused-value -Wunused-variable)
|
||||||
|
add_definitions(-Wno-reorder) # disable this from -Wall, since it happens all over.
|
||||||
|
add_definitions(-std=c++11)
|
||||||
|
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)
|
||||||
|
if(${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
|
||||||
|
set_target_properties(${TARGET} PROPERTIES
|
||||||
|
LINK_FLAGS "-static -static-libgcc -static-libstdc++")
|
||||||
|
endif()
|
||||||
|
endif(WIN32)
|
||||||
|
endfunction(glslang_set_link_args)
|
||||||
|
|
||||||
|
# We depend on these for later projects, so they should come first.
|
||||||
|
add_subdirectory(External)
|
||||||
|
|
||||||
|
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)
|
||||||
|
add_subdirectory(gtests)
|
|
@ -0,0 +1,105 @@
|
||||||
|
# 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)
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Suppress all warnings from external projects.
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS -w)
|
||||||
|
|
||||||
|
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)
|
||||||
|
add_subdirectory(googletest)
|
||||||
|
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()
|
|
@ -0,0 +1,11 @@
|
||||||
|
set(SOURCES InitializeDll.cpp InitializeDll.h)
|
||||||
|
|
||||||
|
add_library(OGLCompiler STATIC ${SOURCES})
|
||||||
|
set_property(TARGET OGLCompiler PROPERTY FOLDER glslang)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
source_group("Source" FILES ${SOURCES})
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
install(TARGETS OGLCompiler
|
||||||
|
ARCHIVE DESTINATION lib)
|
|
@ -0,0 +1,155 @@
|
||||||
|
//
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
InitializeMemoryPools();
|
||||||
|
|
||||||
|
if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
|
||||||
|
assert(0 && "InitThread(): Unable to set init flag.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeGlobalPools();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DetachProcess()
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ShFinalize();
|
||||||
|
|
||||||
|
success = DetachThread();
|
||||||
|
|
||||||
|
FreePoolIndex();
|
||||||
|
|
||||||
|
OS_FreeTLSIndex(ThreadInitializeIndex);
|
||||||
|
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace glslang
|
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// 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();
|
||||||
|
bool DetachProcess();
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // __INITIALIZEDLL_H
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
|
@ -0,0 +1,306 @@
|
||||||
|
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 includes where to get binaries, and is kept up to date
|
||||||
|
regarding the feature level of glslang.
|
||||||
|
|
||||||
|
glslang
|
||||||
|
=======
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/KhronosGroup/glslang.svg?branch=master)](https://travis-ci.org/KhronosGroup/glslang)
|
||||||
|
[![Build status](https://ci.appveyor.com/api/projects/status/q6fi9cb0qnhkla68/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/glslang/branch/master)
|
||||||
|
|
||||||
|
An OpenGL and OpenGL ES shader front end and validator.
|
||||||
|
|
||||||
|
There are several components:
|
||||||
|
|
||||||
|
1. A GLSL/ESSL front-end for reference validation and translation of GLSL/ESSL into an AST.
|
||||||
|
|
||||||
|
2. An HLSL front-end for translation of a broad generic HLL into the AST. See [issue 362](https://github.com/KhronosGroup/glslang/issues/362) and [issue 701](https://github.com/KhronosGroup/glslang/issues/701) for current status.
|
||||||
|
|
||||||
|
3. A SPIR-V back end for translating the AST to SPIR-V.
|
||||||
|
|
||||||
|
4. A standalone wrapper, `glslangValidator`, that can be used as a command-line tool for the above.
|
||||||
|
|
||||||
|
How to add a feature protected by a version/extension/stage/profile: See the
|
||||||
|
comment in `glslang/MachineIndependent/Versions.cpp`.
|
||||||
|
|
||||||
|
Tasks waiting to be done are documented as GitHub issues.
|
||||||
|
|
||||||
|
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
|
||||||
|
--------
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
* [CMake][cmake]: for generating compilation targets.
|
||||||
|
* [bison][bison]: _optional_, but needed when changing the grammar (glslang.y).
|
||||||
|
* [googletest][googletest]: _optional_, but should use if making any changes to glslang.
|
||||||
|
|
||||||
|
### Build steps
|
||||||
|
|
||||||
|
#### 1) Check-Out this project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd <parent of where you want glslang to be>
|
||||||
|
# If using SSH
|
||||||
|
git clone git@github.com:KhronosGroup/glslang.git
|
||||||
|
# Or if using HTTPS
|
||||||
|
git clone https://github.com/KhronosGroup/glslang.git
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 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
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3) Configure
|
||||||
|
|
||||||
|
Assume the source directory is `$SOURCE_DIR` and
|
||||||
|
the build directory is `$BUILD_DIR`:
|
||||||
|
|
||||||
|
For building on Linux (assuming using the Ninja generator):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd $BUILD_DIR
|
||||||
|
|
||||||
|
cmake -GNinja -DCMAKE_BUILD_TYPE={Debug|Release|RelWithDebInfo} \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=`pwd`/install $SOURCE_DIR
|
||||||
|
```
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
#### 4) Build and Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# for Linux:
|
||||||
|
ninja install
|
||||||
|
|
||||||
|
# for Windows:
|
||||||
|
cmake --build . --config {Release|Debug|MinSizeRel|RelWithDebInfo} \
|
||||||
|
--target install
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
bison --defines=MachineIndependent/glslang_tab.cpp.h
|
||||||
|
-t MachineIndependent/glslang.y
|
||||||
|
-o MachineIndependent/glslang_tab.cpp
|
||||||
|
```
|
||||||
|
|
||||||
|
The above command is also available in the bash script at
|
||||||
|
`glslang/updateGrammar`.
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
```cxx
|
||||||
|
const char* GetEsslVersionString();
|
||||||
|
const char* GetGlslVersionString();
|
||||||
|
bool InitializeProcess();
|
||||||
|
void FinalizeProcess();
|
||||||
|
|
||||||
|
class TShader
|
||||||
|
bool parse(...);
|
||||||
|
void setStrings(...);
|
||||||
|
const char* getInfoLog();
|
||||||
|
|
||||||
|
class TProgram
|
||||||
|
void addShader(...);
|
||||||
|
bool link(...);
|
||||||
|
const char* getInfoLog();
|
||||||
|
Reflection queries
|
||||||
|
```
|
||||||
|
|
||||||
|
See `ShaderLang.h` and the usage of it in `StandAlone/StandAlone.cpp` for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
### C Functional Interface (orignal)
|
||||||
|
|
||||||
|
This interface is in roughly the first 2/3 of `ShaderLang.h`, and referred to
|
||||||
|
as the `Sh*()` interface, as all the entry points start `Sh`.
|
||||||
|
|
||||||
|
The `Sh*()` interface takes a "compiler" call-back object, which it calls after
|
||||||
|
building call back that is passed the AST and can then execute a backend on it.
|
||||||
|
|
||||||
|
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 propogated 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`
|
||||||
|
|
||||||
|
|
||||||
|
[cmake]: https://cmake.org/
|
||||||
|
[bison]: https://www.gnu.org/software/bison/
|
||||||
|
[googletest]: https://github.com/google/googletest
|
||||||
|
[bison-gnu-win32]: http://gnuwin32.sourceforge.net/packages/bison.htm
|
|
@ -0,0 +1,57 @@
|
||||||
|
set(SOURCES
|
||||||
|
GlslangToSpv.cpp
|
||||||
|
InReadableOrder.cpp
|
||||||
|
Logger.cpp
|
||||||
|
SpvBuilder.cpp
|
||||||
|
doc.cpp
|
||||||
|
disassemble.cpp)
|
||||||
|
|
||||||
|
set(SPVREMAP_SOURCES
|
||||||
|
SPVRemapper.cpp
|
||||||
|
doc.cpp)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
bitutils.h
|
||||||
|
spirv.hpp
|
||||||
|
GLSL.std.450.h
|
||||||
|
GLSL.ext.KHR.h
|
||||||
|
GlslangToSpv.h
|
||||||
|
hex_float.h
|
||||||
|
Logger.h
|
||||||
|
SpvBuilder.h
|
||||||
|
spvIR.h
|
||||||
|
doc.h
|
||||||
|
disassemble.h)
|
||||||
|
|
||||||
|
set(SPVREMAP_HEADERS
|
||||||
|
SPVRemapper.h
|
||||||
|
doc.h)
|
||||||
|
|
||||||
|
if(ENABLE_AMD_EXTENSIONS)
|
||||||
|
list(APPEND
|
||||||
|
HEADERS
|
||||||
|
GLSL.ext.AMD.h)
|
||||||
|
endif(ENABLE_AMD_EXTENSIONS)
|
||||||
|
|
||||||
|
if(ENABLE_NV_EXTENSIONS)
|
||||||
|
list(APPEND
|
||||||
|
HEADERS
|
||||||
|
GLSL.ext.NV.h)
|
||||||
|
endif(ENABLE_NV_EXTENSIONS)
|
||||||
|
|
||||||
|
add_library(SPIRV STATIC ${SOURCES} ${HEADERS})
|
||||||
|
set_property(TARGET SPIRV PROPERTY FOLDER glslang)
|
||||||
|
target_link_libraries(SPIRV glslang)
|
||||||
|
|
||||||
|
add_library(SPVRemapper STATIC ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||||
|
set_property(TARGET SPVRemapper PROPERTY FOLDER glslang)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
||||||
|
source_group("Source" FILES ${SPVREMAP_SOURCES} ${SPVREMAP_HEADERS})
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
install(TARGETS SPIRV SPVRemapper
|
||||||
|
ARCHIVE DESTINATION lib)
|
||||||
|
|
||||||
|
install(FILES ${HEADERS} ${SPVREMAP_HEADERS} DESTINATION include/SPIRV/)
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
** 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
|
||||||
|
|
||||||
|
enum BuiltIn;
|
||||||
|
enum Decoration;
|
||||||
|
enum Op;
|
||||||
|
|
||||||
|
static const int GLSLextAMDVersion = 100;
|
||||||
|
static const int GLSLextAMDRevision = 2;
|
||||||
|
|
||||||
|
// SPV_AMD_shader_ballot
|
||||||
|
static const char* const E_SPV_AMD_shader_ballot = "SPV_AMD_shader_ballot";
|
||||||
|
|
||||||
|
static const Op OpGroupIAddNonUniformAMD = static_cast<Op>(5000);
|
||||||
|
static const Op OpGroupFAddNonUniformAMD = static_cast<Op>(5001);
|
||||||
|
static const Op OpGroupFMinNonUniformAMD = static_cast<Op>(5002);
|
||||||
|
static const Op OpGroupUMinNonUniformAMD = static_cast<Op>(5003);
|
||||||
|
static const Op OpGroupSMinNonUniformAMD = static_cast<Op>(5004);
|
||||||
|
static const Op OpGroupFMaxNonUniformAMD = static_cast<Op>(5005);
|
||||||
|
static const Op OpGroupUMaxNonUniformAMD = static_cast<Op>(5006);
|
||||||
|
static const Op OpGroupSMaxNonUniformAMD = static_cast<Op>(5007);
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
static const BuiltIn BuiltInBaryCoordNoPerspAMD = static_cast<BuiltIn>(4992);
|
||||||
|
static const BuiltIn BuiltInBaryCoordNoPerspCentroidAMD = static_cast<BuiltIn>(4993);
|
||||||
|
static const BuiltIn BuiltInBaryCoordNoPerspSampleAMD = static_cast<BuiltIn>(4994);
|
||||||
|
static const BuiltIn BuiltInBaryCoordSmoothAMD = static_cast<BuiltIn>(4995);
|
||||||
|
static const BuiltIn BuiltInBaryCoordSmoothCentroidAMD = static_cast<BuiltIn>(4996);
|
||||||
|
static const BuiltIn BuiltInBaryCoordSmoothSampleAMD = static_cast<BuiltIn>(4997);
|
||||||
|
static const BuiltIn BuiltInBaryCoordPullModelAMD = static_cast<BuiltIn>(4998);
|
||||||
|
|
||||||
|
static const Decoration DecorationExplicitInterpAMD = static_cast<Decoration>(4999);
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextAMD_H
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextKHR_H
|
||||||
|
#define GLSLextKHR_H
|
||||||
|
|
||||||
|
enum BuiltIn;
|
||||||
|
enum Op;
|
||||||
|
enum Capability;
|
||||||
|
|
||||||
|
static const int GLSLextKHRVersion = 100;
|
||||||
|
static const int GLSLextKHRRevision = 1;
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextKHR_H
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2017 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextNV_H
|
||||||
|
#define GLSLextNV_H
|
||||||
|
|
||||||
|
enum BuiltIn;
|
||||||
|
enum Decoration;
|
||||||
|
enum Op;
|
||||||
|
enum Capability;
|
||||||
|
|
||||||
|
static const int GLSLextNVVersion = 100;
|
||||||
|
static const int GLSLextNVRevision = 5;
|
||||||
|
|
||||||
|
//SPV_NV_sample_mask_override_coverage
|
||||||
|
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
||||||
|
|
||||||
|
//SPV_NV_geometry_shader_passthrough
|
||||||
|
const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
|
||||||
|
|
||||||
|
//SPV_NV_viewport_array2
|
||||||
|
const char* const E_SPV_NV_viewport_array2 = "SPV_NV_viewport_array2";
|
||||||
|
const char* const E_ARB_shader_viewport_layer_array = "SPV_ARB_shader_viewport_layer_array";
|
||||||
|
|
||||||
|
//SPV_NV_stereo_view_rendering
|
||||||
|
const char* const E_SPV_NV_stereo_view_rendering = "SPV_NV_stereo_view_rendering";
|
||||||
|
|
||||||
|
//SPV_NVX_multiview_per_view_attributes
|
||||||
|
const char* const E_SPV_NVX_multiview_per_view_attributes = "SPV_NVX_multiview_per_view_attributes";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextNV_H
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
** 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
|
@ -0,0 +1,54 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014 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.
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1900
|
||||||
|
#pragma warning(disable : 4464) // relative include path contains '..'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../glslang/Include/intermediate.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
void GetSpirvVersion(std::string&);
|
||||||
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv);
|
||||||
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv, spv::SpvBuildLogger* logger);
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
//
|
||||||
|
// 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_map>
|
||||||
|
|
||||||
|
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:
|
||||||
|
explicit ReadableOrderTraverser(std::function<void(Block*)> callback) : callback_(callback) {}
|
||||||
|
// Visits the block if it hasn't been visited already and isn't currently
|
||||||
|
// being delayed. Invokes callback(block), then descends into its
|
||||||
|
// successors. Delays merge-block and continue-block processing until all
|
||||||
|
// the branches have been completed.
|
||||||
|
void visit(Block* block)
|
||||||
|
{
|
||||||
|
assert(block);
|
||||||
|
if (visited_[block] || delayed_[block])
|
||||||
|
return;
|
||||||
|
callback_(block);
|
||||||
|
visited_[block] = true;
|
||||||
|
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_[mergeBlock] = true;
|
||||||
|
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
|
||||||
|
Id continueId = mergeInst->getIdOperand(1);
|
||||||
|
continueBlock =
|
||||||
|
block->getParent().getParent().getInstruction(continueId)->getBlock();
|
||||||
|
delayed_[continueBlock] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto successors = block->getSuccessors();
|
||||||
|
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
||||||
|
visit(*it);
|
||||||
|
if (continueBlock) {
|
||||||
|
delayed_[continueBlock] = false;
|
||||||
|
visit(continueBlock);
|
||||||
|
}
|
||||||
|
if (mergeBlock) {
|
||||||
|
delayed_[mergeBlock] = false;
|
||||||
|
visit(mergeBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void(Block*)> callback_;
|
||||||
|
// Whether a block has already been visited or is being delayed.
|
||||||
|
std::unordered_map<Block *, bool> visited_, delayed_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void spv::inReadableOrder(Block* root, std::function<void(Block*)> callback)
|
||||||
|
{
|
||||||
|
ReadableOrderTraverser(callback).visit(root);
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
//
|
||||||
|
// 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 "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
|
|
@ -0,0 +1,74 @@
|
||||||
|
//
|
||||||
|
// 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() {}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,296 @@
|
||||||
|
//
|
||||||
|
// 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>
|
||||||
|
|
||||||
|
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 || _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) { }
|
||||||
|
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 { 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
|
||||||
|
|
||||||
|
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
|
@ -0,0 +1,598 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-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.
|
||||||
|
|
||||||
|
//
|
||||||
|
// "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>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
public:
|
||||||
|
Builder(unsigned int userNumber, SpvBuildLogger* logger);
|
||||||
|
virtual ~Builder();
|
||||||
|
|
||||||
|
static const int maxMatrixSize = 4;
|
||||||
|
|
||||||
|
void setSource(spv::SourceLanguage lang, int version)
|
||||||
|
{
|
||||||
|
source = lang;
|
||||||
|
sourceVersion = version;
|
||||||
|
}
|
||||||
|
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
|
||||||
|
void addExtension(const char* ext) { extensions.insert(ext); }
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For creating new types (will return old type if the requested one was already made).
|
||||||
|
Id makeVoidType();
|
||||||
|
Id makeBoolType();
|
||||||
|
Id makePointer(StorageClass, Id type);
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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 isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
||||||
|
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
bool isBoolType(Id typeId) const { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
|
||||||
|
bool 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; }
|
||||||
|
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(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 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 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 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);
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
Id makeFloat16Constant(float f16, bool specConstant = false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 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 addLine(Id target, Id fileName, int line, int column);
|
||||||
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||||
|
|
||||||
|
// 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<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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Load from an Id and return it
|
||||||
|
Id createLoad(Id lValue);
|
||||||
|
|
||||||
|
// 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 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 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 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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&);
|
||||||
|
|
||||||
|
// 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, Builder& builder);
|
||||||
|
~If() {}
|
||||||
|
|
||||||
|
void makeBeginElse();
|
||||||
|
void makeEndIf();
|
||||||
|
|
||||||
|
private:
|
||||||
|
If(const If&);
|
||||||
|
If& operator=(If&);
|
||||||
|
|
||||||
|
Builder& builder;
|
||||||
|
Id condition;
|
||||||
|
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, int numSegments, const std::vector<int>& caseValues,
|
||||||
|
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
|
||||||
|
|
||||||
|
// 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&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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.indexChain.push_back(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
|
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType);
|
||||||
|
|
||||||
|
// push a variable component selection onto the access chain; supporting only one, so unsided
|
||||||
|
void accessChainPushComponent(Id component, Id preSwizzleBaseType)
|
||||||
|
{
|
||||||
|
accessChain.component = component;
|
||||||
|
if (accessChain.preSwizzleBaseType == NoType)
|
||||||
|
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use accessChain and swizzle to store value
|
||||||
|
void accessChainStore(Id rvalue);
|
||||||
|
|
||||||
|
// use accessChain and swizzle to load an r-value
|
||||||
|
Id accessChainLoad(Decoration precision, Id ResultType);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// Remove OpDecorate instructions whose operands are defined in unreachable
|
||||||
|
// blocks.
|
||||||
|
void eliminateDeadDecorations();
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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) const;
|
||||||
|
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
|
||||||
|
Id findCompositeConstant(Op typeClass, const std::vector<Id>& comps) const;
|
||||||
|
Id collapseAccessChain();
|
||||||
|
void transferAccessChainSwizzle(bool dynamic);
|
||||||
|
void simplifyAccessChainSwizzle();
|
||||||
|
void createAndSetNoPredecessorBlock(const char*);
|
||||||
|
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
||||||
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
|
|
||||||
|
SourceLanguage source;
|
||||||
|
int sourceVersion;
|
||||||
|
std::set<std::string> extensions;
|
||||||
|
std::vector<const char*> sourceExtensions;
|
||||||
|
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> > 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> > lines;
|
||||||
|
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
|
||||||
|
std::vector<Instruction*> groupedConstants[OpConstant]; // all types appear before OpConstant
|
||||||
|
std::vector<Instruction*> groupedTypes[OpConstant];
|
||||||
|
|
||||||
|
// stack of switches
|
||||||
|
std::stack<Block*> switchMerges;
|
||||||
|
|
||||||
|
// Our loop stack.
|
||||||
|
std::stack<LoopBlocks> loops;
|
||||||
|
|
||||||
|
// The stream for outputing warnings and errors.
|
||||||
|
SpvBuildLogger* logger;
|
||||||
|
}; // end Builder class
|
||||||
|
|
||||||
|
}; // end spv namespace
|
||||||
|
|
||||||
|
#endif // SpvBuilder_H
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef LIBSPIRV_UTIL_BITUTILS_H_
|
||||||
|
#define LIBSPIRV_UTIL_BITUTILS_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace spvutils {
|
||||||
|
|
||||||
|
// Performs a bitwise copy of source to the destination type Dest.
|
||||||
|
template <typename Dest, typename Src>
|
||||||
|
Dest BitwiseCast(Src source) {
|
||||||
|
Dest dest;
|
||||||
|
static_assert(sizeof(source) == sizeof(dest),
|
||||||
|
"BitwiseCast: Source and destination must have the same size");
|
||||||
|
std::memcpy(&dest, &source, sizeof(dest));
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBits<T, First, Num> returns an integer of type <T> with bits set
|
||||||
|
// for position <First> through <First + Num - 1>, counting from the least
|
||||||
|
// significant bit. In particular when Num == 0, no positions are set to 1.
|
||||||
|
// A static assert will be triggered if First + Num > sizeof(T) * 8, that is,
|
||||||
|
// a bit that will not fit in the underlying type is set.
|
||||||
|
template <typename T, size_t First = 0, size_t Num = 0>
|
||||||
|
struct SetBits {
|
||||||
|
static_assert(First < sizeof(T) * 8,
|
||||||
|
"Tried to set a bit that is shifted too far.");
|
||||||
|
const static T get = (T(1) << First) | SetBits<T, First + 1, Num - 1>::get;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t Last>
|
||||||
|
struct SetBits<T, Last, 0> {
|
||||||
|
const static T get = T(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is all compile-time so we can put our tests right here.
|
||||||
|
static_assert(SetBits<uint32_t, 0, 0>::get == uint32_t(0x00000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 1>::get == uint32_t(0x00000001),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 31, 1>::get == uint32_t(0x80000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 1, 2>::get == uint32_t(0x00000006),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 30, 2>::get == uint32_t(0xc0000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 31>::get == uint32_t(0x7FFFFFFF),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 32>::get == uint32_t(0xFFFFFFFF),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 16, 16>::get == uint32_t(0xFFFF0000),
|
||||||
|
"SetBits failed");
|
||||||
|
|
||||||
|
static_assert(SetBits<uint64_t, 0, 1>::get == uint64_t(0x0000000000000001LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 63, 1>::get == uint64_t(0x8000000000000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 62, 2>::get == uint64_t(0xc000000000000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 31, 1>::get == uint64_t(0x0000000080000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 16, 16>::get == uint64_t(0x00000000FFFF0000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
|
||||||
|
} // namespace spvutils
|
||||||
|
|
||||||
|
#endif // LIBSPIRV_UTIL_BITUTILS_H_
|
|
@ -0,0 +1,695 @@
|
||||||
|
//
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
extern "C" {
|
||||||
|
// Include C-based headers that don't have a namespace
|
||||||
|
#include "GLSL.std.450.h"
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
#include "GLSL.ext.AMD.h"
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
#include "GLSL.ext.NV.h"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void Kill(std::ostream& out, const char* message)
|
||||||
|
{
|
||||||
|
out << std::endl << "Disassembly failed: " << message << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to identify the extended instruction library imported when printing
|
||||||
|
enum ExtInstSet {
|
||||||
|
GLSL450Inst,
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
GLSLextAMDInst,
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
GLSLextNVInst,
|
||||||
|
#endif
|
||||||
|
OpenCLExtInst,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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:
|
||||||
|
idDescriptor[resultId] = "int";
|
||||||
|
break;
|
||||||
|
case OpTypeFloat:
|
||||||
|
idDescriptor[resultId] = "float";
|
||||||
|
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);
|
||||||
|
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 (0 == memcmp("OpenCL", name, 6)) {
|
||||||
|
extInstSet = OpenCLExtInst;
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
|
||||||
|
extInstSet = GLSLextAMDInst;
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
}else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) {
|
||||||
|
extInstSet = GLSLextNVInst;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
unsigned entrypoint = stream[word - 1];
|
||||||
|
if (extInstSet == GLSL450Inst) {
|
||||||
|
if (entrypoint < GLSLstd450Count) {
|
||||||
|
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
||||||
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
} else if (extInstSet == GLSLextAMDInst) {
|
||||||
|
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
|
||||||
|
#endif
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
}
|
||||||
|
else if (extInstSet == GLSLextNVInst) {
|
||||||
|
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OperandOptionalLiteralString:
|
||||||
|
case OperandLiteralString:
|
||||||
|
numOperands -= disassembleString();
|
||||||
|
break;
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
|
{
|
||||||
|
if (strcmp(name, spv::E_SPV_AMD_shader_ballot) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case SwizzleInvocationsAMD: return "SwizzleInvocationsAMD";
|
||||||
|
case SwizzleInvocationsMaskedAMD: return "SwizzleInvocationsMaskedAMD";
|
||||||
|
case WriteInvocationAMD: return "WriteInvocationAMD";
|
||||||
|
case MbcntAMD: return "MbcntAMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, spv::E_SPV_AMD_shader_trinary_minmax) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case FMin3AMD: return "FMin3AMD";
|
||||||
|
case UMin3AMD: return "UMin3AMD";
|
||||||
|
case SMin3AMD: return "SMin3AMD";
|
||||||
|
case FMax3AMD: return "FMax3AMD";
|
||||||
|
case UMax3AMD: return "UMax3AMD";
|
||||||
|
case SMax3AMD: return "SMax3AMD";
|
||||||
|
case FMid3AMD: return "FMid3AMD";
|
||||||
|
case UMid3AMD: return "UMid3AMD";
|
||||||
|
case SMid3AMD: return "SMid3AMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, spv::E_SPV_AMD_shader_explicit_vertex_parameter) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case InterpolateAtVertexAMD: return "InterpolateAtVertexAMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(name, spv::E_SPV_AMD_gcn_shader) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case CubeFaceIndexAMD: return "CubeFaceIndexAMD";
|
||||||
|
case CubeFaceCoordAMD: return "CubeFaceCoordAMD";
|
||||||
|
case TimeAMD: return "TimeAMD";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Bad";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
|
{
|
||||||
|
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 ||
|
||||||
|
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||||
|
case DecorationPassthroughNV: return "PassthroughNV";
|
||||||
|
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||||
|
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||||
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
|
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||||
|
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
||||||
|
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
|
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
|
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
||||||
|
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||||
|
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "Bad";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
||||||
|
{
|
||||||
|
SpirvStream SpirvStream(out, stream);
|
||||||
|
spv::Parameterize();
|
||||||
|
GLSLstd450GetDebugNames(GlslStd450DebugNames);
|
||||||
|
SpirvStream.validate();
|
||||||
|
SpirvStream.processInstructions();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end namespace spv
|
|
@ -0,0 +1,52 @@
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
|
||||||
|
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
|
@ -0,0 +1,260 @@
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#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) { }
|
||||||
|
EnumCaps caps;
|
||||||
|
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;
|
||||||
|
EnumCaps capabilities;
|
||||||
|
OpcodeClass opClass;
|
||||||
|
OperandParameters operands;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int typePresent : 1;
|
||||||
|
int resultPresent : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const int OpcodeCeiling = 321;
|
||||||
|
|
||||||
|
// 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
|
@ -0,0 +1,952 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// This header is automatically generated by the same tool that creates
|
||||||
|
// the Binary Section of the SPIR-V specification.
|
||||||
|
|
||||||
|
// Enumeration tokens for SPIR-V, in various styles:
|
||||||
|
// C, C++, C++11, JSON, Lua, Python
|
||||||
|
//
|
||||||
|
// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
|
||||||
|
// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
|
||||||
|
// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
|
||||||
|
// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
|
||||||
|
// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
|
||||||
|
//
|
||||||
|
// Some tokens act like mask values, which can be OR'd together,
|
||||||
|
// while others are mutually exclusive. The mask-like ones have
|
||||||
|
// "Mask" in their name, and a parallel enum that has the shift
|
||||||
|
// amount (1 << x) for each corresponding enumerant.
|
||||||
|
|
||||||
|
#ifndef spirv_HPP
|
||||||
|
#define spirv_HPP
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
typedef unsigned int Id;
|
||||||
|
|
||||||
|
#define SPV_VERSION 0x10000
|
||||||
|
#define SPV_REVISION 10
|
||||||
|
|
||||||
|
static const unsigned int MagicNumber = 0x07230203;
|
||||||
|
static const unsigned int Version = 0x00010000;
|
||||||
|
static const unsigned int Revision = 10;
|
||||||
|
static const unsigned int OpCodeMask = 0xffff;
|
||||||
|
static const unsigned int WordCountShift = 16;
|
||||||
|
|
||||||
|
enum SourceLanguage {
|
||||||
|
SourceLanguageUnknown = 0,
|
||||||
|
SourceLanguageESSL = 1,
|
||||||
|
SourceLanguageGLSL = 2,
|
||||||
|
SourceLanguageOpenCL_C = 3,
|
||||||
|
SourceLanguageOpenCL_CPP = 4,
|
||||||
|
SourceLanguageMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ExecutionModel {
|
||||||
|
ExecutionModelVertex = 0,
|
||||||
|
ExecutionModelTessellationControl = 1,
|
||||||
|
ExecutionModelTessellationEvaluation = 2,
|
||||||
|
ExecutionModelGeometry = 3,
|
||||||
|
ExecutionModelFragment = 4,
|
||||||
|
ExecutionModelGLCompute = 5,
|
||||||
|
ExecutionModelKernel = 6,
|
||||||
|
ExecutionModelMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AddressingModel {
|
||||||
|
AddressingModelLogical = 0,
|
||||||
|
AddressingModelPhysical32 = 1,
|
||||||
|
AddressingModelPhysical64 = 2,
|
||||||
|
AddressingModelMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemoryModel {
|
||||||
|
MemoryModelSimple = 0,
|
||||||
|
MemoryModelGLSL450 = 1,
|
||||||
|
MemoryModelOpenCL = 2,
|
||||||
|
MemoryModelMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ExecutionMode {
|
||||||
|
ExecutionModeInvocations = 0,
|
||||||
|
ExecutionModeSpacingEqual = 1,
|
||||||
|
ExecutionModeSpacingFractionalEven = 2,
|
||||||
|
ExecutionModeSpacingFractionalOdd = 3,
|
||||||
|
ExecutionModeVertexOrderCw = 4,
|
||||||
|
ExecutionModeVertexOrderCcw = 5,
|
||||||
|
ExecutionModePixelCenterInteger = 6,
|
||||||
|
ExecutionModeOriginUpperLeft = 7,
|
||||||
|
ExecutionModeOriginLowerLeft = 8,
|
||||||
|
ExecutionModeEarlyFragmentTests = 9,
|
||||||
|
ExecutionModePointMode = 10,
|
||||||
|
ExecutionModeXfb = 11,
|
||||||
|
ExecutionModeDepthReplacing = 12,
|
||||||
|
ExecutionModeDepthGreater = 14,
|
||||||
|
ExecutionModeDepthLess = 15,
|
||||||
|
ExecutionModeDepthUnchanged = 16,
|
||||||
|
ExecutionModeLocalSize = 17,
|
||||||
|
ExecutionModeLocalSizeHint = 18,
|
||||||
|
ExecutionModeInputPoints = 19,
|
||||||
|
ExecutionModeInputLines = 20,
|
||||||
|
ExecutionModeInputLinesAdjacency = 21,
|
||||||
|
ExecutionModeTriangles = 22,
|
||||||
|
ExecutionModeInputTrianglesAdjacency = 23,
|
||||||
|
ExecutionModeQuads = 24,
|
||||||
|
ExecutionModeIsolines = 25,
|
||||||
|
ExecutionModeOutputVertices = 26,
|
||||||
|
ExecutionModeOutputPoints = 27,
|
||||||
|
ExecutionModeOutputLineStrip = 28,
|
||||||
|
ExecutionModeOutputTriangleStrip = 29,
|
||||||
|
ExecutionModeVecTypeHint = 30,
|
||||||
|
ExecutionModeContractionOff = 31,
|
||||||
|
ExecutionModeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum StorageClass {
|
||||||
|
StorageClassUniformConstant = 0,
|
||||||
|
StorageClassInput = 1,
|
||||||
|
StorageClassUniform = 2,
|
||||||
|
StorageClassOutput = 3,
|
||||||
|
StorageClassWorkgroup = 4,
|
||||||
|
StorageClassCrossWorkgroup = 5,
|
||||||
|
StorageClassPrivate = 6,
|
||||||
|
StorageClassFunction = 7,
|
||||||
|
StorageClassGeneric = 8,
|
||||||
|
StorageClassPushConstant = 9,
|
||||||
|
StorageClassAtomicCounter = 10,
|
||||||
|
StorageClassImage = 11,
|
||||||
|
StorageClassMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Dim {
|
||||||
|
Dim1D = 0,
|
||||||
|
Dim2D = 1,
|
||||||
|
Dim3D = 2,
|
||||||
|
DimCube = 3,
|
||||||
|
DimRect = 4,
|
||||||
|
DimBuffer = 5,
|
||||||
|
DimSubpassData = 6,
|
||||||
|
DimMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SamplerAddressingMode {
|
||||||
|
SamplerAddressingModeNone = 0,
|
||||||
|
SamplerAddressingModeClampToEdge = 1,
|
||||||
|
SamplerAddressingModeClamp = 2,
|
||||||
|
SamplerAddressingModeRepeat = 3,
|
||||||
|
SamplerAddressingModeRepeatMirrored = 4,
|
||||||
|
SamplerAddressingModeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SamplerFilterMode {
|
||||||
|
SamplerFilterModeNearest = 0,
|
||||||
|
SamplerFilterModeLinear = 1,
|
||||||
|
SamplerFilterModeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImageFormat {
|
||||||
|
ImageFormatUnknown = 0,
|
||||||
|
ImageFormatRgba32f = 1,
|
||||||
|
ImageFormatRgba16f = 2,
|
||||||
|
ImageFormatR32f = 3,
|
||||||
|
ImageFormatRgba8 = 4,
|
||||||
|
ImageFormatRgba8Snorm = 5,
|
||||||
|
ImageFormatRg32f = 6,
|
||||||
|
ImageFormatRg16f = 7,
|
||||||
|
ImageFormatR11fG11fB10f = 8,
|
||||||
|
ImageFormatR16f = 9,
|
||||||
|
ImageFormatRgba16 = 10,
|
||||||
|
ImageFormatRgb10A2 = 11,
|
||||||
|
ImageFormatRg16 = 12,
|
||||||
|
ImageFormatRg8 = 13,
|
||||||
|
ImageFormatR16 = 14,
|
||||||
|
ImageFormatR8 = 15,
|
||||||
|
ImageFormatRgba16Snorm = 16,
|
||||||
|
ImageFormatRg16Snorm = 17,
|
||||||
|
ImageFormatRg8Snorm = 18,
|
||||||
|
ImageFormatR16Snorm = 19,
|
||||||
|
ImageFormatR8Snorm = 20,
|
||||||
|
ImageFormatRgba32i = 21,
|
||||||
|
ImageFormatRgba16i = 22,
|
||||||
|
ImageFormatRgba8i = 23,
|
||||||
|
ImageFormatR32i = 24,
|
||||||
|
ImageFormatRg32i = 25,
|
||||||
|
ImageFormatRg16i = 26,
|
||||||
|
ImageFormatRg8i = 27,
|
||||||
|
ImageFormatR16i = 28,
|
||||||
|
ImageFormatR8i = 29,
|
||||||
|
ImageFormatRgba32ui = 30,
|
||||||
|
ImageFormatRgba16ui = 31,
|
||||||
|
ImageFormatRgba8ui = 32,
|
||||||
|
ImageFormatR32ui = 33,
|
||||||
|
ImageFormatRgb10a2ui = 34,
|
||||||
|
ImageFormatRg32ui = 35,
|
||||||
|
ImageFormatRg16ui = 36,
|
||||||
|
ImageFormatRg8ui = 37,
|
||||||
|
ImageFormatR16ui = 38,
|
||||||
|
ImageFormatR8ui = 39,
|
||||||
|
ImageFormatMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImageChannelOrder {
|
||||||
|
ImageChannelOrderR = 0,
|
||||||
|
ImageChannelOrderA = 1,
|
||||||
|
ImageChannelOrderRG = 2,
|
||||||
|
ImageChannelOrderRA = 3,
|
||||||
|
ImageChannelOrderRGB = 4,
|
||||||
|
ImageChannelOrderRGBA = 5,
|
||||||
|
ImageChannelOrderBGRA = 6,
|
||||||
|
ImageChannelOrderARGB = 7,
|
||||||
|
ImageChannelOrderIntensity = 8,
|
||||||
|
ImageChannelOrderLuminance = 9,
|
||||||
|
ImageChannelOrderRx = 10,
|
||||||
|
ImageChannelOrderRGx = 11,
|
||||||
|
ImageChannelOrderRGBx = 12,
|
||||||
|
ImageChannelOrderDepth = 13,
|
||||||
|
ImageChannelOrderDepthStencil = 14,
|
||||||
|
ImageChannelOrdersRGB = 15,
|
||||||
|
ImageChannelOrdersRGBx = 16,
|
||||||
|
ImageChannelOrdersRGBA = 17,
|
||||||
|
ImageChannelOrdersBGRA = 18,
|
||||||
|
ImageChannelOrderABGR = 19,
|
||||||
|
ImageChannelOrderMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImageChannelDataType {
|
||||||
|
ImageChannelDataTypeSnormInt8 = 0,
|
||||||
|
ImageChannelDataTypeSnormInt16 = 1,
|
||||||
|
ImageChannelDataTypeUnormInt8 = 2,
|
||||||
|
ImageChannelDataTypeUnormInt16 = 3,
|
||||||
|
ImageChannelDataTypeUnormShort565 = 4,
|
||||||
|
ImageChannelDataTypeUnormShort555 = 5,
|
||||||
|
ImageChannelDataTypeUnormInt101010 = 6,
|
||||||
|
ImageChannelDataTypeSignedInt8 = 7,
|
||||||
|
ImageChannelDataTypeSignedInt16 = 8,
|
||||||
|
ImageChannelDataTypeSignedInt32 = 9,
|
||||||
|
ImageChannelDataTypeUnsignedInt8 = 10,
|
||||||
|
ImageChannelDataTypeUnsignedInt16 = 11,
|
||||||
|
ImageChannelDataTypeUnsignedInt32 = 12,
|
||||||
|
ImageChannelDataTypeHalfFloat = 13,
|
||||||
|
ImageChannelDataTypeFloat = 14,
|
||||||
|
ImageChannelDataTypeUnormInt24 = 15,
|
||||||
|
ImageChannelDataTypeUnormInt101010_2 = 16,
|
||||||
|
ImageChannelDataTypeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImageOperandsShift {
|
||||||
|
ImageOperandsBiasShift = 0,
|
||||||
|
ImageOperandsLodShift = 1,
|
||||||
|
ImageOperandsGradShift = 2,
|
||||||
|
ImageOperandsConstOffsetShift = 3,
|
||||||
|
ImageOperandsOffsetShift = 4,
|
||||||
|
ImageOperandsConstOffsetsShift = 5,
|
||||||
|
ImageOperandsSampleShift = 6,
|
||||||
|
ImageOperandsMinLodShift = 7,
|
||||||
|
ImageOperandsMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ImageOperandsMask {
|
||||||
|
ImageOperandsMaskNone = 0,
|
||||||
|
ImageOperandsBiasMask = 0x00000001,
|
||||||
|
ImageOperandsLodMask = 0x00000002,
|
||||||
|
ImageOperandsGradMask = 0x00000004,
|
||||||
|
ImageOperandsConstOffsetMask = 0x00000008,
|
||||||
|
ImageOperandsOffsetMask = 0x00000010,
|
||||||
|
ImageOperandsConstOffsetsMask = 0x00000020,
|
||||||
|
ImageOperandsSampleMask = 0x00000040,
|
||||||
|
ImageOperandsMinLodMask = 0x00000080,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FPFastMathModeShift {
|
||||||
|
FPFastMathModeNotNaNShift = 0,
|
||||||
|
FPFastMathModeNotInfShift = 1,
|
||||||
|
FPFastMathModeNSZShift = 2,
|
||||||
|
FPFastMathModeAllowRecipShift = 3,
|
||||||
|
FPFastMathModeFastShift = 4,
|
||||||
|
FPFastMathModeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FPFastMathModeMask {
|
||||||
|
FPFastMathModeMaskNone = 0,
|
||||||
|
FPFastMathModeNotNaNMask = 0x00000001,
|
||||||
|
FPFastMathModeNotInfMask = 0x00000002,
|
||||||
|
FPFastMathModeNSZMask = 0x00000004,
|
||||||
|
FPFastMathModeAllowRecipMask = 0x00000008,
|
||||||
|
FPFastMathModeFastMask = 0x00000010,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FPRoundingMode {
|
||||||
|
FPRoundingModeRTE = 0,
|
||||||
|
FPRoundingModeRTZ = 1,
|
||||||
|
FPRoundingModeRTP = 2,
|
||||||
|
FPRoundingModeRTN = 3,
|
||||||
|
FPRoundingModeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LinkageType {
|
||||||
|
LinkageTypeExport = 0,
|
||||||
|
LinkageTypeImport = 1,
|
||||||
|
LinkageTypeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AccessQualifier {
|
||||||
|
AccessQualifierReadOnly = 0,
|
||||||
|
AccessQualifierWriteOnly = 1,
|
||||||
|
AccessQualifierReadWrite = 2,
|
||||||
|
AccessQualifierMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FunctionParameterAttribute {
|
||||||
|
FunctionParameterAttributeZext = 0,
|
||||||
|
FunctionParameterAttributeSext = 1,
|
||||||
|
FunctionParameterAttributeByVal = 2,
|
||||||
|
FunctionParameterAttributeSret = 3,
|
||||||
|
FunctionParameterAttributeNoAlias = 4,
|
||||||
|
FunctionParameterAttributeNoCapture = 5,
|
||||||
|
FunctionParameterAttributeNoWrite = 6,
|
||||||
|
FunctionParameterAttributeNoReadWrite = 7,
|
||||||
|
FunctionParameterAttributeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Decoration {
|
||||||
|
DecorationRelaxedPrecision = 0,
|
||||||
|
DecorationSpecId = 1,
|
||||||
|
DecorationBlock = 2,
|
||||||
|
DecorationBufferBlock = 3,
|
||||||
|
DecorationRowMajor = 4,
|
||||||
|
DecorationColMajor = 5,
|
||||||
|
DecorationArrayStride = 6,
|
||||||
|
DecorationMatrixStride = 7,
|
||||||
|
DecorationGLSLShared = 8,
|
||||||
|
DecorationGLSLPacked = 9,
|
||||||
|
DecorationCPacked = 10,
|
||||||
|
DecorationBuiltIn = 11,
|
||||||
|
DecorationNoPerspective = 13,
|
||||||
|
DecorationFlat = 14,
|
||||||
|
DecorationPatch = 15,
|
||||||
|
DecorationCentroid = 16,
|
||||||
|
DecorationSample = 17,
|
||||||
|
DecorationInvariant = 18,
|
||||||
|
DecorationRestrict = 19,
|
||||||
|
DecorationAliased = 20,
|
||||||
|
DecorationVolatile = 21,
|
||||||
|
DecorationConstant = 22,
|
||||||
|
DecorationCoherent = 23,
|
||||||
|
DecorationNonWritable = 24,
|
||||||
|
DecorationNonReadable = 25,
|
||||||
|
DecorationUniform = 26,
|
||||||
|
DecorationSaturatedConversion = 28,
|
||||||
|
DecorationStream = 29,
|
||||||
|
DecorationLocation = 30,
|
||||||
|
DecorationComponent = 31,
|
||||||
|
DecorationIndex = 32,
|
||||||
|
DecorationBinding = 33,
|
||||||
|
DecorationDescriptorSet = 34,
|
||||||
|
DecorationOffset = 35,
|
||||||
|
DecorationXfbBuffer = 36,
|
||||||
|
DecorationXfbStride = 37,
|
||||||
|
DecorationFuncParamAttr = 38,
|
||||||
|
DecorationFPRoundingMode = 39,
|
||||||
|
DecorationFPFastMathMode = 40,
|
||||||
|
DecorationLinkageAttributes = 41,
|
||||||
|
DecorationNoContraction = 42,
|
||||||
|
DecorationInputAttachmentIndex = 43,
|
||||||
|
DecorationAlignment = 44,
|
||||||
|
DecorationOverrideCoverageNV = 5248,
|
||||||
|
DecorationPassthroughNV = 5250,
|
||||||
|
DecorationViewportRelativeNV = 5252,
|
||||||
|
DecorationSecondaryViewportRelativeNV = 5256,
|
||||||
|
DecorationMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BuiltIn {
|
||||||
|
BuiltInPosition = 0,
|
||||||
|
BuiltInPointSize = 1,
|
||||||
|
BuiltInClipDistance = 3,
|
||||||
|
BuiltInCullDistance = 4,
|
||||||
|
BuiltInVertexId = 5,
|
||||||
|
BuiltInInstanceId = 6,
|
||||||
|
BuiltInPrimitiveId = 7,
|
||||||
|
BuiltInInvocationId = 8,
|
||||||
|
BuiltInLayer = 9,
|
||||||
|
BuiltInViewportIndex = 10,
|
||||||
|
BuiltInTessLevelOuter = 11,
|
||||||
|
BuiltInTessLevelInner = 12,
|
||||||
|
BuiltInTessCoord = 13,
|
||||||
|
BuiltInPatchVertices = 14,
|
||||||
|
BuiltInFragCoord = 15,
|
||||||
|
BuiltInPointCoord = 16,
|
||||||
|
BuiltInFrontFacing = 17,
|
||||||
|
BuiltInSampleId = 18,
|
||||||
|
BuiltInSamplePosition = 19,
|
||||||
|
BuiltInSampleMask = 20,
|
||||||
|
BuiltInFragDepth = 22,
|
||||||
|
BuiltInHelperInvocation = 23,
|
||||||
|
BuiltInNumWorkgroups = 24,
|
||||||
|
BuiltInWorkgroupSize = 25,
|
||||||
|
BuiltInWorkgroupId = 26,
|
||||||
|
BuiltInLocalInvocationId = 27,
|
||||||
|
BuiltInGlobalInvocationId = 28,
|
||||||
|
BuiltInLocalInvocationIndex = 29,
|
||||||
|
BuiltInWorkDim = 30,
|
||||||
|
BuiltInGlobalSize = 31,
|
||||||
|
BuiltInEnqueuedWorkgroupSize = 32,
|
||||||
|
BuiltInGlobalOffset = 33,
|
||||||
|
BuiltInGlobalLinearId = 34,
|
||||||
|
BuiltInSubgroupSize = 36,
|
||||||
|
BuiltInSubgroupMaxSize = 37,
|
||||||
|
BuiltInNumSubgroups = 38,
|
||||||
|
BuiltInNumEnqueuedSubgroups = 39,
|
||||||
|
BuiltInSubgroupId = 40,
|
||||||
|
BuiltInSubgroupLocalInvocationId = 41,
|
||||||
|
BuiltInVertexIndex = 42,
|
||||||
|
BuiltInInstanceIndex = 43,
|
||||||
|
BuiltInSubgroupEqMaskKHR = 4416,
|
||||||
|
BuiltInSubgroupGeMaskKHR = 4417,
|
||||||
|
BuiltInSubgroupGtMaskKHR = 4418,
|
||||||
|
BuiltInSubgroupLeMaskKHR = 4419,
|
||||||
|
BuiltInSubgroupLtMaskKHR = 4420,
|
||||||
|
BuiltInBaseVertex = 4424,
|
||||||
|
BuiltInBaseInstance = 4425,
|
||||||
|
BuiltInDrawIndex = 4426,
|
||||||
|
BuiltInDeviceIndex = 4438,
|
||||||
|
BuiltInViewIndex = 4440,
|
||||||
|
BuiltInViewportMaskNV = 5253,
|
||||||
|
BuiltInSecondaryPositionNV = 5257,
|
||||||
|
BuiltInSecondaryViewportMaskNV = 5258,
|
||||||
|
BuiltInPositionPerViewNV = 5261,
|
||||||
|
BuiltInViewportMaskPerViewNV = 5262,
|
||||||
|
BuiltInMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SelectionControlShift {
|
||||||
|
SelectionControlFlattenShift = 0,
|
||||||
|
SelectionControlDontFlattenShift = 1,
|
||||||
|
SelectionControlMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SelectionControlMask {
|
||||||
|
SelectionControlMaskNone = 0,
|
||||||
|
SelectionControlFlattenMask = 0x00000001,
|
||||||
|
SelectionControlDontFlattenMask = 0x00000002,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LoopControlShift {
|
||||||
|
LoopControlUnrollShift = 0,
|
||||||
|
LoopControlDontUnrollShift = 1,
|
||||||
|
LoopControlMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LoopControlMask {
|
||||||
|
LoopControlMaskNone = 0,
|
||||||
|
LoopControlUnrollMask = 0x00000001,
|
||||||
|
LoopControlDontUnrollMask = 0x00000002,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FunctionControlShift {
|
||||||
|
FunctionControlInlineShift = 0,
|
||||||
|
FunctionControlDontInlineShift = 1,
|
||||||
|
FunctionControlPureShift = 2,
|
||||||
|
FunctionControlConstShift = 3,
|
||||||
|
FunctionControlMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FunctionControlMask {
|
||||||
|
FunctionControlMaskNone = 0,
|
||||||
|
FunctionControlInlineMask = 0x00000001,
|
||||||
|
FunctionControlDontInlineMask = 0x00000002,
|
||||||
|
FunctionControlPureMask = 0x00000004,
|
||||||
|
FunctionControlConstMask = 0x00000008,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemorySemanticsShift {
|
||||||
|
MemorySemanticsAcquireShift = 1,
|
||||||
|
MemorySemanticsReleaseShift = 2,
|
||||||
|
MemorySemanticsAcquireReleaseShift = 3,
|
||||||
|
MemorySemanticsSequentiallyConsistentShift = 4,
|
||||||
|
MemorySemanticsUniformMemoryShift = 6,
|
||||||
|
MemorySemanticsSubgroupMemoryShift = 7,
|
||||||
|
MemorySemanticsWorkgroupMemoryShift = 8,
|
||||||
|
MemorySemanticsCrossWorkgroupMemoryShift = 9,
|
||||||
|
MemorySemanticsAtomicCounterMemoryShift = 10,
|
||||||
|
MemorySemanticsImageMemoryShift = 11,
|
||||||
|
MemorySemanticsMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemorySemanticsMask {
|
||||||
|
MemorySemanticsMaskNone = 0,
|
||||||
|
MemorySemanticsAcquireMask = 0x00000002,
|
||||||
|
MemorySemanticsReleaseMask = 0x00000004,
|
||||||
|
MemorySemanticsAcquireReleaseMask = 0x00000008,
|
||||||
|
MemorySemanticsSequentiallyConsistentMask = 0x00000010,
|
||||||
|
MemorySemanticsUniformMemoryMask = 0x00000040,
|
||||||
|
MemorySemanticsSubgroupMemoryMask = 0x00000080,
|
||||||
|
MemorySemanticsWorkgroupMemoryMask = 0x00000100,
|
||||||
|
MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
|
||||||
|
MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
|
||||||
|
MemorySemanticsImageMemoryMask = 0x00000800,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemoryAccessShift {
|
||||||
|
MemoryAccessVolatileShift = 0,
|
||||||
|
MemoryAccessAlignedShift = 1,
|
||||||
|
MemoryAccessNontemporalShift = 2,
|
||||||
|
MemoryAccessMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemoryAccessMask {
|
||||||
|
MemoryAccessMaskNone = 0,
|
||||||
|
MemoryAccessVolatileMask = 0x00000001,
|
||||||
|
MemoryAccessAlignedMask = 0x00000002,
|
||||||
|
MemoryAccessNontemporalMask = 0x00000004,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Scope {
|
||||||
|
ScopeCrossDevice = 0,
|
||||||
|
ScopeDevice = 1,
|
||||||
|
ScopeWorkgroup = 2,
|
||||||
|
ScopeSubgroup = 3,
|
||||||
|
ScopeInvocation = 4,
|
||||||
|
ScopeMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GroupOperation {
|
||||||
|
GroupOperationReduce = 0,
|
||||||
|
GroupOperationInclusiveScan = 1,
|
||||||
|
GroupOperationExclusiveScan = 2,
|
||||||
|
GroupOperationMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KernelEnqueueFlags {
|
||||||
|
KernelEnqueueFlagsNoWait = 0,
|
||||||
|
KernelEnqueueFlagsWaitKernel = 1,
|
||||||
|
KernelEnqueueFlagsWaitWorkGroup = 2,
|
||||||
|
KernelEnqueueFlagsMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KernelProfilingInfoShift {
|
||||||
|
KernelProfilingInfoCmdExecTimeShift = 0,
|
||||||
|
KernelProfilingInfoMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KernelProfilingInfoMask {
|
||||||
|
KernelProfilingInfoMaskNone = 0,
|
||||||
|
KernelProfilingInfoCmdExecTimeMask = 0x00000001,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Capability {
|
||||||
|
CapabilityMatrix = 0,
|
||||||
|
CapabilityShader = 1,
|
||||||
|
CapabilityGeometry = 2,
|
||||||
|
CapabilityTessellation = 3,
|
||||||
|
CapabilityAddresses = 4,
|
||||||
|
CapabilityLinkage = 5,
|
||||||
|
CapabilityKernel = 6,
|
||||||
|
CapabilityVector16 = 7,
|
||||||
|
CapabilityFloat16Buffer = 8,
|
||||||
|
CapabilityFloat16 = 9,
|
||||||
|
CapabilityFloat64 = 10,
|
||||||
|
CapabilityInt64 = 11,
|
||||||
|
CapabilityInt64Atomics = 12,
|
||||||
|
CapabilityImageBasic = 13,
|
||||||
|
CapabilityImageReadWrite = 14,
|
||||||
|
CapabilityImageMipmap = 15,
|
||||||
|
CapabilityPipes = 17,
|
||||||
|
CapabilityGroups = 18,
|
||||||
|
CapabilityDeviceEnqueue = 19,
|
||||||
|
CapabilityLiteralSampler = 20,
|
||||||
|
CapabilityAtomicStorage = 21,
|
||||||
|
CapabilityInt16 = 22,
|
||||||
|
CapabilityTessellationPointSize = 23,
|
||||||
|
CapabilityGeometryPointSize = 24,
|
||||||
|
CapabilityImageGatherExtended = 25,
|
||||||
|
CapabilityStorageImageMultisample = 27,
|
||||||
|
CapabilityUniformBufferArrayDynamicIndexing = 28,
|
||||||
|
CapabilitySampledImageArrayDynamicIndexing = 29,
|
||||||
|
CapabilityStorageBufferArrayDynamicIndexing = 30,
|
||||||
|
CapabilityStorageImageArrayDynamicIndexing = 31,
|
||||||
|
CapabilityClipDistance = 32,
|
||||||
|
CapabilityCullDistance = 33,
|
||||||
|
CapabilityImageCubeArray = 34,
|
||||||
|
CapabilitySampleRateShading = 35,
|
||||||
|
CapabilityImageRect = 36,
|
||||||
|
CapabilitySampledRect = 37,
|
||||||
|
CapabilityGenericPointer = 38,
|
||||||
|
CapabilityInt8 = 39,
|
||||||
|
CapabilityInputAttachment = 40,
|
||||||
|
CapabilitySparseResidency = 41,
|
||||||
|
CapabilityMinLod = 42,
|
||||||
|
CapabilitySampled1D = 43,
|
||||||
|
CapabilityImage1D = 44,
|
||||||
|
CapabilitySampledCubeArray = 45,
|
||||||
|
CapabilitySampledBuffer = 46,
|
||||||
|
CapabilityImageBuffer = 47,
|
||||||
|
CapabilityImageMSArray = 48,
|
||||||
|
CapabilityStorageImageExtendedFormats = 49,
|
||||||
|
CapabilityImageQuery = 50,
|
||||||
|
CapabilityDerivativeControl = 51,
|
||||||
|
CapabilityInterpolationFunction = 52,
|
||||||
|
CapabilityTransformFeedback = 53,
|
||||||
|
CapabilityGeometryStreams = 54,
|
||||||
|
CapabilityStorageImageReadWithoutFormat = 55,
|
||||||
|
CapabilityStorageImageWriteWithoutFormat = 56,
|
||||||
|
CapabilityMultiViewport = 57,
|
||||||
|
CapabilitySubgroupBallotKHR = 4423,
|
||||||
|
CapabilityDrawParameters = 4427,
|
||||||
|
CapabilitySubgroupVoteKHR = 4431,
|
||||||
|
CapabilityStorageUniformBufferBlock16 = 4433,
|
||||||
|
CapabilityStorageUniform16 = 4434,
|
||||||
|
CapabilityStoragePushConstant16 = 4435,
|
||||||
|
CapabilityStorageInputOutput16 = 4436,
|
||||||
|
CapabilityDeviceGroup = 4437,
|
||||||
|
CapabilityMultiView = 4439,
|
||||||
|
CapabilitySampleMaskOverrideCoverageNV = 5249,
|
||||||
|
CapabilityGeometryShaderPassthroughNV = 5251,
|
||||||
|
CapabilityShaderViewportIndexLayerNV = 5254,
|
||||||
|
CapabilityShaderViewportMaskNV = 5255,
|
||||||
|
CapabilityShaderStereoViewNV = 5259,
|
||||||
|
CapabilityPerViewAttributesNV = 5260,
|
||||||
|
CapabilityMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Op {
|
||||||
|
OpNop = 0,
|
||||||
|
OpUndef = 1,
|
||||||
|
OpSourceContinued = 2,
|
||||||
|
OpSource = 3,
|
||||||
|
OpSourceExtension = 4,
|
||||||
|
OpName = 5,
|
||||||
|
OpMemberName = 6,
|
||||||
|
OpString = 7,
|
||||||
|
OpLine = 8,
|
||||||
|
OpExtension = 10,
|
||||||
|
OpExtInstImport = 11,
|
||||||
|
OpExtInst = 12,
|
||||||
|
OpMemoryModel = 14,
|
||||||
|
OpEntryPoint = 15,
|
||||||
|
OpExecutionMode = 16,
|
||||||
|
OpCapability = 17,
|
||||||
|
OpTypeVoid = 19,
|
||||||
|
OpTypeBool = 20,
|
||||||
|
OpTypeInt = 21,
|
||||||
|
OpTypeFloat = 22,
|
||||||
|
OpTypeVector = 23,
|
||||||
|
OpTypeMatrix = 24,
|
||||||
|
OpTypeImage = 25,
|
||||||
|
OpTypeSampler = 26,
|
||||||
|
OpTypeSampledImage = 27,
|
||||||
|
OpTypeArray = 28,
|
||||||
|
OpTypeRuntimeArray = 29,
|
||||||
|
OpTypeStruct = 30,
|
||||||
|
OpTypeOpaque = 31,
|
||||||
|
OpTypePointer = 32,
|
||||||
|
OpTypeFunction = 33,
|
||||||
|
OpTypeEvent = 34,
|
||||||
|
OpTypeDeviceEvent = 35,
|
||||||
|
OpTypeReserveId = 36,
|
||||||
|
OpTypeQueue = 37,
|
||||||
|
OpTypePipe = 38,
|
||||||
|
OpTypeForwardPointer = 39,
|
||||||
|
OpConstantTrue = 41,
|
||||||
|
OpConstantFalse = 42,
|
||||||
|
OpConstant = 43,
|
||||||
|
OpConstantComposite = 44,
|
||||||
|
OpConstantSampler = 45,
|
||||||
|
OpConstantNull = 46,
|
||||||
|
OpSpecConstantTrue = 48,
|
||||||
|
OpSpecConstantFalse = 49,
|
||||||
|
OpSpecConstant = 50,
|
||||||
|
OpSpecConstantComposite = 51,
|
||||||
|
OpSpecConstantOp = 52,
|
||||||
|
OpFunction = 54,
|
||||||
|
OpFunctionParameter = 55,
|
||||||
|
OpFunctionEnd = 56,
|
||||||
|
OpFunctionCall = 57,
|
||||||
|
OpVariable = 59,
|
||||||
|
OpImageTexelPointer = 60,
|
||||||
|
OpLoad = 61,
|
||||||
|
OpStore = 62,
|
||||||
|
OpCopyMemory = 63,
|
||||||
|
OpCopyMemorySized = 64,
|
||||||
|
OpAccessChain = 65,
|
||||||
|
OpInBoundsAccessChain = 66,
|
||||||
|
OpPtrAccessChain = 67,
|
||||||
|
OpArrayLength = 68,
|
||||||
|
OpGenericPtrMemSemantics = 69,
|
||||||
|
OpInBoundsPtrAccessChain = 70,
|
||||||
|
OpDecorate = 71,
|
||||||
|
OpMemberDecorate = 72,
|
||||||
|
OpDecorationGroup = 73,
|
||||||
|
OpGroupDecorate = 74,
|
||||||
|
OpGroupMemberDecorate = 75,
|
||||||
|
OpVectorExtractDynamic = 77,
|
||||||
|
OpVectorInsertDynamic = 78,
|
||||||
|
OpVectorShuffle = 79,
|
||||||
|
OpCompositeConstruct = 80,
|
||||||
|
OpCompositeExtract = 81,
|
||||||
|
OpCompositeInsert = 82,
|
||||||
|
OpCopyObject = 83,
|
||||||
|
OpTranspose = 84,
|
||||||
|
OpSampledImage = 86,
|
||||||
|
OpImageSampleImplicitLod = 87,
|
||||||
|
OpImageSampleExplicitLod = 88,
|
||||||
|
OpImageSampleDrefImplicitLod = 89,
|
||||||
|
OpImageSampleDrefExplicitLod = 90,
|
||||||
|
OpImageSampleProjImplicitLod = 91,
|
||||||
|
OpImageSampleProjExplicitLod = 92,
|
||||||
|
OpImageSampleProjDrefImplicitLod = 93,
|
||||||
|
OpImageSampleProjDrefExplicitLod = 94,
|
||||||
|
OpImageFetch = 95,
|
||||||
|
OpImageGather = 96,
|
||||||
|
OpImageDrefGather = 97,
|
||||||
|
OpImageRead = 98,
|
||||||
|
OpImageWrite = 99,
|
||||||
|
OpImage = 100,
|
||||||
|
OpImageQueryFormat = 101,
|
||||||
|
OpImageQueryOrder = 102,
|
||||||
|
OpImageQuerySizeLod = 103,
|
||||||
|
OpImageQuerySize = 104,
|
||||||
|
OpImageQueryLod = 105,
|
||||||
|
OpImageQueryLevels = 106,
|
||||||
|
OpImageQuerySamples = 107,
|
||||||
|
OpConvertFToU = 109,
|
||||||
|
OpConvertFToS = 110,
|
||||||
|
OpConvertSToF = 111,
|
||||||
|
OpConvertUToF = 112,
|
||||||
|
OpUConvert = 113,
|
||||||
|
OpSConvert = 114,
|
||||||
|
OpFConvert = 115,
|
||||||
|
OpQuantizeToF16 = 116,
|
||||||
|
OpConvertPtrToU = 117,
|
||||||
|
OpSatConvertSToU = 118,
|
||||||
|
OpSatConvertUToS = 119,
|
||||||
|
OpConvertUToPtr = 120,
|
||||||
|
OpPtrCastToGeneric = 121,
|
||||||
|
OpGenericCastToPtr = 122,
|
||||||
|
OpGenericCastToPtrExplicit = 123,
|
||||||
|
OpBitcast = 124,
|
||||||
|
OpSNegate = 126,
|
||||||
|
OpFNegate = 127,
|
||||||
|
OpIAdd = 128,
|
||||||
|
OpFAdd = 129,
|
||||||
|
OpISub = 130,
|
||||||
|
OpFSub = 131,
|
||||||
|
OpIMul = 132,
|
||||||
|
OpFMul = 133,
|
||||||
|
OpUDiv = 134,
|
||||||
|
OpSDiv = 135,
|
||||||
|
OpFDiv = 136,
|
||||||
|
OpUMod = 137,
|
||||||
|
OpSRem = 138,
|
||||||
|
OpSMod = 139,
|
||||||
|
OpFRem = 140,
|
||||||
|
OpFMod = 141,
|
||||||
|
OpVectorTimesScalar = 142,
|
||||||
|
OpMatrixTimesScalar = 143,
|
||||||
|
OpVectorTimesMatrix = 144,
|
||||||
|
OpMatrixTimesVector = 145,
|
||||||
|
OpMatrixTimesMatrix = 146,
|
||||||
|
OpOuterProduct = 147,
|
||||||
|
OpDot = 148,
|
||||||
|
OpIAddCarry = 149,
|
||||||
|
OpISubBorrow = 150,
|
||||||
|
OpUMulExtended = 151,
|
||||||
|
OpSMulExtended = 152,
|
||||||
|
OpAny = 154,
|
||||||
|
OpAll = 155,
|
||||||
|
OpIsNan = 156,
|
||||||
|
OpIsInf = 157,
|
||||||
|
OpIsFinite = 158,
|
||||||
|
OpIsNormal = 159,
|
||||||
|
OpSignBitSet = 160,
|
||||||
|
OpLessOrGreater = 161,
|
||||||
|
OpOrdered = 162,
|
||||||
|
OpUnordered = 163,
|
||||||
|
OpLogicalEqual = 164,
|
||||||
|
OpLogicalNotEqual = 165,
|
||||||
|
OpLogicalOr = 166,
|
||||||
|
OpLogicalAnd = 167,
|
||||||
|
OpLogicalNot = 168,
|
||||||
|
OpSelect = 169,
|
||||||
|
OpIEqual = 170,
|
||||||
|
OpINotEqual = 171,
|
||||||
|
OpUGreaterThan = 172,
|
||||||
|
OpSGreaterThan = 173,
|
||||||
|
OpUGreaterThanEqual = 174,
|
||||||
|
OpSGreaterThanEqual = 175,
|
||||||
|
OpULessThan = 176,
|
||||||
|
OpSLessThan = 177,
|
||||||
|
OpULessThanEqual = 178,
|
||||||
|
OpSLessThanEqual = 179,
|
||||||
|
OpFOrdEqual = 180,
|
||||||
|
OpFUnordEqual = 181,
|
||||||
|
OpFOrdNotEqual = 182,
|
||||||
|
OpFUnordNotEqual = 183,
|
||||||
|
OpFOrdLessThan = 184,
|
||||||
|
OpFUnordLessThan = 185,
|
||||||
|
OpFOrdGreaterThan = 186,
|
||||||
|
OpFUnordGreaterThan = 187,
|
||||||
|
OpFOrdLessThanEqual = 188,
|
||||||
|
OpFUnordLessThanEqual = 189,
|
||||||
|
OpFOrdGreaterThanEqual = 190,
|
||||||
|
OpFUnordGreaterThanEqual = 191,
|
||||||
|
OpShiftRightLogical = 194,
|
||||||
|
OpShiftRightArithmetic = 195,
|
||||||
|
OpShiftLeftLogical = 196,
|
||||||
|
OpBitwiseOr = 197,
|
||||||
|
OpBitwiseXor = 198,
|
||||||
|
OpBitwiseAnd = 199,
|
||||||
|
OpNot = 200,
|
||||||
|
OpBitFieldInsert = 201,
|
||||||
|
OpBitFieldSExtract = 202,
|
||||||
|
OpBitFieldUExtract = 203,
|
||||||
|
OpBitReverse = 204,
|
||||||
|
OpBitCount = 205,
|
||||||
|
OpDPdx = 207,
|
||||||
|
OpDPdy = 208,
|
||||||
|
OpFwidth = 209,
|
||||||
|
OpDPdxFine = 210,
|
||||||
|
OpDPdyFine = 211,
|
||||||
|
OpFwidthFine = 212,
|
||||||
|
OpDPdxCoarse = 213,
|
||||||
|
OpDPdyCoarse = 214,
|
||||||
|
OpFwidthCoarse = 215,
|
||||||
|
OpEmitVertex = 218,
|
||||||
|
OpEndPrimitive = 219,
|
||||||
|
OpEmitStreamVertex = 220,
|
||||||
|
OpEndStreamPrimitive = 221,
|
||||||
|
OpControlBarrier = 224,
|
||||||
|
OpMemoryBarrier = 225,
|
||||||
|
OpAtomicLoad = 227,
|
||||||
|
OpAtomicStore = 228,
|
||||||
|
OpAtomicExchange = 229,
|
||||||
|
OpAtomicCompareExchange = 230,
|
||||||
|
OpAtomicCompareExchangeWeak = 231,
|
||||||
|
OpAtomicIIncrement = 232,
|
||||||
|
OpAtomicIDecrement = 233,
|
||||||
|
OpAtomicIAdd = 234,
|
||||||
|
OpAtomicISub = 235,
|
||||||
|
OpAtomicSMin = 236,
|
||||||
|
OpAtomicUMin = 237,
|
||||||
|
OpAtomicSMax = 238,
|
||||||
|
OpAtomicUMax = 239,
|
||||||
|
OpAtomicAnd = 240,
|
||||||
|
OpAtomicOr = 241,
|
||||||
|
OpAtomicXor = 242,
|
||||||
|
OpPhi = 245,
|
||||||
|
OpLoopMerge = 246,
|
||||||
|
OpSelectionMerge = 247,
|
||||||
|
OpLabel = 248,
|
||||||
|
OpBranch = 249,
|
||||||
|
OpBranchConditional = 250,
|
||||||
|
OpSwitch = 251,
|
||||||
|
OpKill = 252,
|
||||||
|
OpReturn = 253,
|
||||||
|
OpReturnValue = 254,
|
||||||
|
OpUnreachable = 255,
|
||||||
|
OpLifetimeStart = 256,
|
||||||
|
OpLifetimeStop = 257,
|
||||||
|
OpGroupAsyncCopy = 259,
|
||||||
|
OpGroupWaitEvents = 260,
|
||||||
|
OpGroupAll = 261,
|
||||||
|
OpGroupAny = 262,
|
||||||
|
OpGroupBroadcast = 263,
|
||||||
|
OpGroupIAdd = 264,
|
||||||
|
OpGroupFAdd = 265,
|
||||||
|
OpGroupFMin = 266,
|
||||||
|
OpGroupUMin = 267,
|
||||||
|
OpGroupSMin = 268,
|
||||||
|
OpGroupFMax = 269,
|
||||||
|
OpGroupUMax = 270,
|
||||||
|
OpGroupSMax = 271,
|
||||||
|
OpReadPipe = 274,
|
||||||
|
OpWritePipe = 275,
|
||||||
|
OpReservedReadPipe = 276,
|
||||||
|
OpReservedWritePipe = 277,
|
||||||
|
OpReserveReadPipePackets = 278,
|
||||||
|
OpReserveWritePipePackets = 279,
|
||||||
|
OpCommitReadPipe = 280,
|
||||||
|
OpCommitWritePipe = 281,
|
||||||
|
OpIsValidReserveId = 282,
|
||||||
|
OpGetNumPipePackets = 283,
|
||||||
|
OpGetMaxPipePackets = 284,
|
||||||
|
OpGroupReserveReadPipePackets = 285,
|
||||||
|
OpGroupReserveWritePipePackets = 286,
|
||||||
|
OpGroupCommitReadPipe = 287,
|
||||||
|
OpGroupCommitWritePipe = 288,
|
||||||
|
OpEnqueueMarker = 291,
|
||||||
|
OpEnqueueKernel = 292,
|
||||||
|
OpGetKernelNDrangeSubGroupCount = 293,
|
||||||
|
OpGetKernelNDrangeMaxSubGroupSize = 294,
|
||||||
|
OpGetKernelWorkGroupSize = 295,
|
||||||
|
OpGetKernelPreferredWorkGroupSizeMultiple = 296,
|
||||||
|
OpRetainEvent = 297,
|
||||||
|
OpReleaseEvent = 298,
|
||||||
|
OpCreateUserEvent = 299,
|
||||||
|
OpIsValidEvent = 300,
|
||||||
|
OpSetUserEventStatus = 301,
|
||||||
|
OpCaptureEventProfilingInfo = 302,
|
||||||
|
OpGetDefaultQueue = 303,
|
||||||
|
OpBuildNDRange = 304,
|
||||||
|
OpImageSparseSampleImplicitLod = 305,
|
||||||
|
OpImageSparseSampleExplicitLod = 306,
|
||||||
|
OpImageSparseSampleDrefImplicitLod = 307,
|
||||||
|
OpImageSparseSampleDrefExplicitLod = 308,
|
||||||
|
OpImageSparseSampleProjImplicitLod = 309,
|
||||||
|
OpImageSparseSampleProjExplicitLod = 310,
|
||||||
|
OpImageSparseSampleProjDrefImplicitLod = 311,
|
||||||
|
OpImageSparseSampleProjDrefExplicitLod = 312,
|
||||||
|
OpImageSparseFetch = 313,
|
||||||
|
OpImageSparseGather = 314,
|
||||||
|
OpImageSparseDrefGather = 315,
|
||||||
|
OpImageSparseTexelsResident = 316,
|
||||||
|
OpNoLine = 317,
|
||||||
|
OpAtomicFlagTestAndSet = 318,
|
||||||
|
OpAtomicFlagClear = 319,
|
||||||
|
OpImageSparseRead = 320,
|
||||||
|
OpSubgroupBallotKHR = 4421,
|
||||||
|
OpSubgroupFirstInvocationKHR = 4422,
|
||||||
|
OpSubgroupAllKHR = 4428,
|
||||||
|
OpSubgroupAnyKHR = 4429,
|
||||||
|
OpSubgroupAllEqualKHR = 4430,
|
||||||
|
OpSubgroupReadInvocationKHR = 4432,
|
||||||
|
OpMax = 0x7fffffff,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Overload operator| for mask bit combining
|
||||||
|
|
||||||
|
inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
|
||||||
|
inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
|
||||||
|
|
||||||
|
} // end namespace spv
|
||||||
|
|
||||||
|
#endif // #ifndef spirv_HPP
|
||||||
|
|
|
@ -0,0 +1,405 @@
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014 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.
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||||
|
(MemorySemanticsMask)(MemorySemanticsSequentiallyConsistentMask |
|
||||||
|
MemorySemanticsUniformMemoryMask |
|
||||||
|
MemorySemanticsSubgroupMemoryMask |
|
||||||
|
MemorySemanticsWorkgroupMemoryMask |
|
||||||
|
MemorySemanticsCrossWorkgroupMemoryMask |
|
||||||
|
MemorySemanticsAtomicCounterMemoryMask |
|
||||||
|
MemorySemanticsImageMemoryMask);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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); }
|
||||||
|
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
||||||
|
void addStringOperand(const char* str)
|
||||||
|
{
|
||||||
|
originalString = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void setBlock(Block* b) { block = b; }
|
||||||
|
Block* getBlock() const { return block; }
|
||||||
|
Op getOpCode() const { return opCode; }
|
||||||
|
int getNumOperands() const { return (int)operands.size(); }
|
||||||
|
Id getResultId() const { return resultId; }
|
||||||
|
Id getTypeId() const { return typeId; }
|
||||||
|
Id getIdOperand(int op) const { return operands[op]; }
|
||||||
|
unsigned int getImmediateOperand(int op) const { return operands[op]; }
|
||||||
|
const char* getStringOperand() const { return originalString.c_str(); }
|
||||||
|
|
||||||
|
// Write out the binary form.
|
||||||
|
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;
|
||||||
|
std::string originalString; // could be optimized away; convenience for getting string operand
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTerminated() const
|
||||||
|
{
|
||||||
|
switch (instructions.back()->getOpCode()) {
|
||||||
|
case OpBranch:
|
||||||
|
case OpBranchConditional:
|
||||||
|
case OpSwitch:
|
||||||
|
case OpKill:
|
||||||
|
case OpReturn:
|
||||||
|
case OpReturnValue:
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
void inReadableOrder(Block* root, std::function<void(Block*)> 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) { return parameterInstructions[p]->getResultId(); }
|
||||||
|
|
||||||
|
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) { 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]->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
|
|
@ -0,0 +1,47 @@
|
||||||
|
add_library(glslang-default-resource-limits
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ResourceLimits.cpp
|
||||||
|
)
|
||||||
|
set_property(TARGET glslang-default-resource-limits PROPERTY FOLDER glslang)
|
||||||
|
|
||||||
|
target_include_directories(glslang-default-resource-limits
|
||||||
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
PUBLIC ${PROJECT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES StandAlone.cpp)
|
||||||
|
set(REMAPPER_SOURCES spirv-remap.cpp)
|
||||||
|
|
||||||
|
add_executable(glslangValidator ${SOURCES})
|
||||||
|
add_executable(spirv-remap ${REMAPPER_SOURCES})
|
||||||
|
set_property(TARGET glslangValidator PROPERTY FOLDER tools)
|
||||||
|
set_property(TARGET spirv-remap PROPERTY FOLDER tools)
|
||||||
|
glslang_set_link_args(glslangValidator)
|
||||||
|
glslang_set_link_args(spirv-remap)
|
||||||
|
|
||||||
|
set(LIBRARIES
|
||||||
|
glslang
|
||||||
|
SPIRV
|
||||||
|
SPVRemapper
|
||||||
|
glslang-default-resource-limits)
|
||||||
|
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(LIBRARIES ${LIBRARIES} psapi)
|
||||||
|
elseif(UNIX)
|
||||||
|
if(NOT ANDROID)
|
||||||
|
set(LIBRARIES ${LIBRARIES} pthread)
|
||||||
|
endif()
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
target_link_libraries(glslangValidator ${LIBRARIES})
|
||||||
|
target_link_libraries(spirv-remap ${LIBRARIES})
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
source_group("Source" FILES ${SOURCES})
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
|
install(TARGETS glslangValidator
|
||||||
|
RUNTIME DESTINATION bin)
|
||||||
|
|
||||||
|
install(TARGETS spirv-remap
|
||||||
|
RUNTIME DESTINATION bin)
|
|
@ -0,0 +1,458 @@
|
||||||
|
//
|
||||||
|
// 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,
|
||||||
|
/* .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"
|
||||||
|
|
||||||
|
<< "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 == "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
|
|
@ -0,0 +1,57 @@
|
||||||
|
//
|
||||||
|
// 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
|
@ -0,0 +1,98 @@
|
||||||
|
//
|
||||||
|
// 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 <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
GetGlobalLock();
|
||||||
|
|
||||||
|
worklist.push_back(item);
|
||||||
|
|
||||||
|
ReleaseGlobalLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool remove(TWorkItem*& item)
|
||||||
|
{
|
||||||
|
GetGlobalLock();
|
||||||
|
|
||||||
|
if (worklist.empty())
|
||||||
|
return false;
|
||||||
|
item = worklist.front();
|
||||||
|
worklist.pop_front();
|
||||||
|
|
||||||
|
ReleaseGlobalLock();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size()
|
||||||
|
{
|
||||||
|
return (int)worklist.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty()
|
||||||
|
{
|
||||||
|
return worklist.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::list<TWorkItem*> worklist;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // WORKLIST_H_INCLUDED
|
|
@ -0,0 +1,343 @@
|
||||||
|
//
|
||||||
|
// 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 " << __DATE__ << " " << __TIME__ << 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");
|
||||||
|
|
||||||
|
std::string errmsg;
|
||||||
|
|
||||||
|
// Main operations: read, remap, and write.
|
||||||
|
execute(inputFile, outputDir, opts, verbosity);
|
||||||
|
|
||||||
|
// If we get here, everything went OK! Nothing more to be done.
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
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
|
|
@ -0,0 +1,227 @@
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
#pragma STDGL invariant(all)
|
||||||
|
|
||||||
|
#line 3000
|
||||||
|
#error line of this error should be 3000
|
||||||
|
|
||||||
|
uniform samplerExternalOES badExt; // syntax ERROR
|
|
@ -0,0 +1,76 @@
|
||||||
|
#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];
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
#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
|
|
@ -0,0 +1,74 @@
|
||||||
|
#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);
|
||||||
|
}
|
|
@ -0,0 +1,248 @@
|
||||||
|
#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
|
|
@ -0,0 +1,203 @@
|
||||||
|
#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);
|
|
@ -0,0 +1,169 @@
|
||||||
|
#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(bl4) <= int(bl4); // true
|
||||||
|
int(bl4.x) > int(bl4.y); // false
|
||||||
|
}
|
||||||
|
|
||||||
|
#extension GL_ARB_texture_gather : enable
|
||||||
|
#extension GL_ARB_texture_rectangle : 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
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
|
@ -0,0 +1,78 @@
|
||||||
|
#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);
|
|
@ -0,0 +1,53 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
#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_device_group
|
||||||
|
#extension GL_EXT_multiview : enable
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void devie()
|
||||||
|
{
|
||||||
|
gl_DeviceIndex;
|
||||||
|
gl_ViewIndex;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
#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;
|
|
@ -0,0 +1,34 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#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
|
|
@ -0,0 +1,161 @@
|
||||||
|
#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
|
|
@ -0,0 +1,187 @@
|
||||||
|
#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
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
#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
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
#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.
|
|
@ -0,0 +1,19 @@
|
||||||
|
#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
|
|
@ -0,0 +1,57 @@
|
||||||
|
#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
|
|
@ -0,0 +1,8 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
out vec4 color1;
|
||||||
|
out vec4 color2;
|
||||||
|
|
||||||
|
void main() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#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()
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
out vec4 color1;
|
||||||
|
|
||||||
|
void main() {}
|
|
@ -0,0 +1,135 @@
|
||||||
|
#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
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
#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
|
||||||
|
}
|
|
@ -0,0 +1,256 @@
|
||||||
|
#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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
passr(qualim2); // ERROR, drops restrict
|
||||||
|
passr(iimg2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
|
@ -0,0 +1,451 @@
|
||||||
|
#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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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_device_group
|
||||||
|
#extension GL_EXT_multiview : enable
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void devie()
|
||||||
|
{
|
||||||
|
gl_DeviceIndex;
|
||||||
|
gl_ViewIndex;
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
#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 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;
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
#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 // ERROR, no size
|
||||||
|
{
|
||||||
|
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
|
||||||
|
}
|
|
@ -0,0 +1,403 @@
|
||||||
|
#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
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
#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
|
|
@ -0,0 +1,8 @@
|
||||||
|
#version 310 es
|
||||||
|
layout (location=0) uniform Block {
|
||||||
|
highp int a[];
|
||||||
|
} uni;
|
||||||
|
layout (location=0) out highp int o;
|
||||||
|
void main() {
|
||||||
|
o = uni.a[2];
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
#version 330 compatibility
|
||||||
|
|
||||||
|
in vec4 inVar;
|
||||||
|
layout(location=0, index=0) out vec4 outVar;
|
||||||
|
|
||||||
|
varying vec4 varyingVar;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = varyingVar; // link ERROR: user output was used
|
||||||
|
gl_FragData[1] = inVar; // link ERROR: user output was used
|
||||||
|
int buffer = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
in gl_PerFragment {
|
||||||
|
vec4 gl_Color;
|
||||||
|
};
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
vec4 c = gl_Color;
|
||||||
|
outVar = inVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
in gl_block { // ERROR
|
||||||
|
int gl_i;
|
||||||
|
} gl_name;
|
||||||
|
|
||||||
|
in myBlock {
|
||||||
|
int gl_i; // ERROR
|
||||||
|
} gl_name; // ERROR
|
||||||
|
|
||||||
|
in gl_PerVertex { // ERROR
|
||||||
|
vec4 gl_FragCoord;
|
||||||
|
} gl_in[];
|
||||||
|
|
||||||
|
in gl_PerVertex { // ERROR
|
||||||
|
vec4 gl_FragCoord;
|
||||||
|
}; // ERROR
|
||||||
|
|
||||||
|
const int start = 6;
|
||||||
|
layout(location = -2) in vec4 v1; // ERROR
|
||||||
|
layout(location = start + 2) in vec4 v2; // ERROR
|
||||||
|
layout(location = 4.7e10) in vec4 v20; // ERROR
|
||||||
|
layout(location = +60) in float v21; // ERROR
|
||||||
|
layout(location = (2)) in float v22; // ERROR
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
float f1;
|
||||||
|
layout(location = 3) float f2; // ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 1) in inblock { // ERROR
|
||||||
|
float f1;
|
||||||
|
layout(location = 3) float f2; // ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 1) uniform ublock { // ERROR
|
||||||
|
float f1;
|
||||||
|
layout(location = 3) float f2; // ERROR
|
||||||
|
} uinst;
|
||||||
|
|
||||||
|
#extension GL_ARB_enhanced_layouts : enable
|
||||||
|
|
||||||
|
layout(location = start) in vec4 v3;
|
||||||
|
layout(location = -2) in vec4 v4; // ERROR
|
||||||
|
layout(location = -start) in vec4 v5; // ERROR
|
||||||
|
layout(location = start*start - 2 - 4) in vec4 v6;
|
||||||
|
layout(location = +61) in float v23;
|
||||||
|
layout(location = (62)) in float v24;
|
||||||
|
|
||||||
|
struct S2 {
|
||||||
|
float f1;
|
||||||
|
layout(location = 3) float f2; // ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(location = 28) in inblock2 {
|
||||||
|
bool b1;
|
||||||
|
float f1;
|
||||||
|
layout(location = 25) float f2;
|
||||||
|
vec4 f3;
|
||||||
|
layout(location = 21) S2 s2;
|
||||||
|
vec4 f4;
|
||||||
|
vec4 f5;
|
||||||
|
} ininst2;
|
||||||
|
|
||||||
|
layout(location = 13) uniform ublock2 { // ERROR
|
||||||
|
float f1;
|
||||||
|
layout(location = 3) float f2; // ERROR
|
||||||
|
} uinst2;
|
||||||
|
|
||||||
|
in inblock3 { // ERROR, mix of location internal with no location external
|
||||||
|
float f1;
|
||||||
|
layout(location = 40) float f2;
|
||||||
|
} in3;
|
||||||
|
|
||||||
|
in ublock4 {
|
||||||
|
layout(location = 50) float f1;
|
||||||
|
layout(location = 51) float f2;
|
||||||
|
} in4;
|
||||||
|
|
||||||
|
layout(location = 33) in struct SS {
|
||||||
|
vec3 a; // gets location 33
|
||||||
|
mat2 b; // gets locations 34 and 35
|
||||||
|
vec4 c[2]; // gets locations 36 and 37
|
||||||
|
layout (location = 38) vec2 A; // ERROR, can't use on struct member
|
||||||
|
} s;
|
||||||
|
|
||||||
|
layout(location = 44) in block {
|
||||||
|
vec4 d; // gets location 44
|
||||||
|
vec4 e; // gets location 45
|
||||||
|
layout(location = 47) vec4 f; // gets location 47
|
||||||
|
vec4 g; // gets location 48
|
||||||
|
layout (location = 41) vec4 h; // gets location 41
|
||||||
|
vec4 i; // gets location 42
|
||||||
|
vec4 j; // gets location 43
|
||||||
|
vec4 k; // ERROR, location 44 already used
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(index=0) out vec4 outVar2; // ERROR: missing explicit location
|
||||||
|
layout(location=0, index=1) out vec4 outVar3; // no error even though location is overlapping
|
||||||
|
layout(location=0, index=1) out vec4 outVar4; // ERROR overlapping
|
||||||
|
layout(location=27, index=0) in vec4 indexIn; // ERROR, not on in
|
||||||
|
layout(location=0, index=0) in; // ERROR, not just on in
|
||||||
|
layout(location=0, index=0) out; // ERROR, need a variable
|
||||||
|
layout(location=26, index=0) out indexBlock { int a; } indexBlockI; // ERROR, not on a block
|
||||||
|
|
||||||
|
uniform sampler1D samp1D;
|
||||||
|
uniform sampler2DShadow samp2Ds;
|
||||||
|
|
||||||
|
void qlod()
|
||||||
|
{
|
||||||
|
vec2 lod;
|
||||||
|
float pf;
|
||||||
|
vec2 pf2;
|
||||||
|
vec3 pf3;
|
||||||
|
|
||||||
|
lod = textureQueryLod(samp1D, pf); // ERROR, not until 400
|
||||||
|
lod = textureQueryLod(samp2Ds, pf2); // ERROR, not until 400
|
||||||
|
}
|
||||||
|
|
||||||
|
int precise; // okay, not a keyword yet
|
||||||
|
struct SKeyMem { int precise; } KeyMem; // okay, not a keyword yet
|
||||||
|
|
||||||
|
void fooKeyMem()
|
||||||
|
{
|
||||||
|
KeyMem.precise;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(location=28, index=2) out vec4 outIndex2; // ERROR index out of range
|
|
@ -0,0 +1,12 @@
|
||||||
|
#version 330 compatibility
|
||||||
|
|
||||||
|
in vec4 inVar;
|
||||||
|
out vec4 outVar;
|
||||||
|
|
||||||
|
varying vec4 varyingVar;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = varyingVar;
|
||||||
|
gl_FragData[1] = inVar * gl_ModelViewMatrix;
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
#version 400 core
|
||||||
|
|
||||||
|
in vec2 c2D;
|
||||||
|
flat in int i;
|
||||||
|
out vec4 outp;
|
||||||
|
uniform sampler2D arrayedSampler[5];
|
||||||
|
uniform usampler2DRect samp2dr;
|
||||||
|
uniform isampler2DArray isamp2DA;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 v;
|
||||||
|
v = texture(arrayedSampler[i], c2D);
|
||||||
|
outp.x = gl_ClipDistance[1];
|
||||||
|
|
||||||
|
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, offsets not constant
|
||||||
|
uv4 = textureGatherOffsets(samp2dr, c2D, constOffsets, 2);
|
||||||
|
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(i));
|
||||||
|
|
||||||
|
vec4 c = gl_FragCoord;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(location = 4) in vec4 vl; // ERROR, not supported
|
||||||
|
|
||||||
|
#ifdef GL_ARB_separate_shader_objects
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
#endif
|
||||||
|
|
||||||
|
layout(location = 6) in vec4 vl2;
|
||||||
|
|
||||||
|
layout(location = 3) uniform vec3 uv3;
|
||||||
|
|
||||||
|
layout(location = 5) in vec4 gl_Color; // ERROR, layout
|
||||||
|
noperspective in float gl_ClipDistance[4]; // ERROR, can't change qualifier
|
||||||
|
|
||||||
|
layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; // ERROR, declared after use
|
||||||
|
|
||||||
|
uniform sampler2DRectShadow u2drs;
|
||||||
|
|
||||||
|
void foo23()
|
||||||
|
{
|
||||||
|
const ivec2[3] offsets = ivec2[3](ivec2(1,2), ivec2(3,4), ivec2(15,16));
|
||||||
|
|
||||||
|
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), ivec2(c2D)); // ERROR, offset not constant
|
||||||
|
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), offsets[1]);
|
||||||
|
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), offsets[2]); // ERROR, offset out of range
|
||||||
|
textureProjGradOffset(u2drs, outp, vec2(0.0), vec2(0.0), ivec2(-10, 20)); // ERROR, offset out of range
|
||||||
|
}
|
||||||
|
|
||||||
|
patch in vec4 patchIn; // ERROR
|
||||||
|
patch out vec4 patchOut; // ERROR
|
||||||
|
|
||||||
|
void foo24()
|
||||||
|
{
|
||||||
|
dvec3 df, di;
|
||||||
|
df = modf(dvec3(outp.xyz), di);
|
||||||
|
}
|
||||||
|
|
||||||
|
in float in1;
|
||||||
|
in vec2 in2;
|
||||||
|
in vec3 in3;
|
||||||
|
in vec4 in4;
|
||||||
|
|
||||||
|
void foodc1()
|
||||||
|
{
|
||||||
|
vec2 v2 = dFdxFine(in2); // ERROR
|
||||||
|
vec3 v3 = dFdyCoarse(in3); // ERROR
|
||||||
|
vec4 v4 = fwidthCoarse(in4) + fwidthFine(in4); // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
#extension GL_ARB_derivative_control : enable
|
||||||
|
|
||||||
|
void foodc2()
|
||||||
|
{
|
||||||
|
vec2 v2 = dFdxFine(in2);
|
||||||
|
vec3 v3 = dFdyCoarse(in3);
|
||||||
|
vec4 v4 = fwidthCoarse(in4) + fwidthFine(in4);
|
||||||
|
|
||||||
|
uint u1;
|
||||||
|
ivec3 i3;
|
||||||
|
ivec2 i2;
|
||||||
|
v2 = frexp(v2, i2);
|
||||||
|
v3 = ldexp(v3, i3);
|
||||||
|
|
||||||
|
u1 = packUnorm4x8(v4);
|
||||||
|
u1 = packSnorm4x8(v4);
|
||||||
|
v4 = unpackUnorm4x8(u1);
|
||||||
|
v4 = unpackSnorm4x8(u1);
|
||||||
|
|
||||||
|
double d;
|
||||||
|
uvec2 u2;
|
||||||
|
d = packDouble2x32(u2);
|
||||||
|
u2 = unpackDouble2x32(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
sample in vec4 colorSampIn;
|
||||||
|
sample out vec4 colorSampleBad; // ERROR
|
||||||
|
noperspective in vec4 colorfsi;
|
||||||
|
sample in vec3 sampInArray[4];
|
||||||
|
smooth in float scalarIn;
|
||||||
|
flat centroid in vec2 colorfc;
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
float x;
|
||||||
|
};
|
||||||
|
|
||||||
|
in S s1;
|
||||||
|
sample S s2;
|
||||||
|
|
||||||
|
void interp()
|
||||||
|
{
|
||||||
|
interpolateAtCentroid(colorfc);
|
||||||
|
interpolateAtCentroid(colorSampIn);
|
||||||
|
interpolateAtCentroid(colorfsi);
|
||||||
|
interpolateAtCentroid(scalarIn);
|
||||||
|
interpolateAtCentroid(sampInArray); // ERROR
|
||||||
|
interpolateAtCentroid(sampInArray[2]);
|
||||||
|
interpolateAtCentroid(sampInArray[2].xy); // ERROR
|
||||||
|
|
||||||
|
interpolateAtSample(sampInArray, 1); // ERROR
|
||||||
|
interpolateAtSample(sampInArray[i], 0);
|
||||||
|
interpolateAtSample(s1.x, 2);
|
||||||
|
interpolateAtSample(scalarIn, 1);
|
||||||
|
|
||||||
|
interpolateAtOffset(sampInArray, vec2(0.2)); // ERROR
|
||||||
|
interpolateAtOffset(sampInArray[2], vec2(0.2));
|
||||||
|
interpolateAtOffset(sampInArray[2].xy, vec2(0.2)); // ERROR, no swizzle
|
||||||
|
interpolateAtOffset(scalarIn + scalarIn, vec2(0.2)); // ERROR, no binary ops other than dereference
|
||||||
|
interpolateAtOffset(s2.x, vec2(0.2)); // ERROR
|
||||||
|
|
||||||
|
float f;
|
||||||
|
interpolateAtCentroid(f); // ERROR, not interpolant
|
||||||
|
interpolateAtSample(outp, 0); // ERROR, not interpolant
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform sampler1D samp1D;
|
||||||
|
uniform isampler2D isamp2D;
|
||||||
|
uniform usampler3D usamp3D;
|
||||||
|
uniform samplerCube sampCube;
|
||||||
|
uniform isampler1DArray isamp1DA;
|
||||||
|
uniform usampler2DArray usamp2DA;
|
||||||
|
uniform isamplerCubeArray isampCubeA;
|
||||||
|
|
||||||
|
uniform sampler1DShadow samp1Ds;
|
||||||
|
uniform sampler2DShadow samp2Ds;
|
||||||
|
uniform samplerCubeShadow sampCubes;
|
||||||
|
uniform sampler1DArrayShadow samp1DAs;
|
||||||
|
uniform sampler2DArrayShadow samp2DAs;
|
||||||
|
uniform samplerCubeArrayShadow sampCubeAs;
|
||||||
|
|
||||||
|
uniform samplerBuffer sampBuf;
|
||||||
|
uniform sampler2DRect sampRect;
|
||||||
|
|
||||||
|
void qlod()
|
||||||
|
{
|
||||||
|
vec2 lod;
|
||||||
|
float pf;
|
||||||
|
vec2 pf2;
|
||||||
|
vec3 pf3;
|
||||||
|
|
||||||
|
lod = textureQueryLod(samp1D, pf);
|
||||||
|
lod = textureQueryLod(isamp2D, pf2);
|
||||||
|
lod = textureQueryLod(usamp3D, pf3);
|
||||||
|
lod = textureQueryLod(sampCube, pf3);
|
||||||
|
lod = textureQueryLod(isamp1DA, pf);
|
||||||
|
lod = textureQueryLod(usamp2DA, pf2);
|
||||||
|
lod = textureQueryLod(isampCubeA, pf3);
|
||||||
|
|
||||||
|
lod = textureQueryLod(samp1Ds, pf);
|
||||||
|
lod = textureQueryLod(samp2Ds, pf2);
|
||||||
|
lod = textureQueryLod(sampCubes, pf3);
|
||||||
|
lod = textureQueryLod(samp1DAs, pf);
|
||||||
|
lod = textureQueryLod(samp2DAs, pf2);
|
||||||
|
lod = textureQueryLod(sampCubeAs, pf3);
|
||||||
|
|
||||||
|
lod = textureQueryLod(sampBuf, pf); // ERROR
|
||||||
|
lod = textureQueryLod(sampRect, pf2); // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SKeyMem { int precise; } KeyMem; // ERROR, keyword can't be a member
|
||||||
|
|
||||||
|
uniform uint uu;
|
||||||
|
out int iout;
|
||||||
|
|
||||||
|
void bitwiseConv()
|
||||||
|
{
|
||||||
|
iout = uu & i;
|
||||||
|
iout += uu ^ i;
|
||||||
|
iout += i | uu;
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
#version 400 core
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
EmitStreamVertex(1);
|
||||||
|
EndStreamPrimitive(0);
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
int id = gl_InvocationID;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(invocations = 4) in outbn { int a; } bn[]; // ERROR, not on a block
|
||||||
|
layout(max_vertices = 127) out;
|
||||||
|
layout(invocations = 4) in;
|
||||||
|
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
in gl_PerVertex { // testing input arrays with a block redeclaration, see 420.geom for without
|
||||||
|
vec4 gl_Position;
|
||||||
|
layout(std140, location = 3) patch float gl_PointSize; // ERRORs...
|
||||||
|
} gl_in[];
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
gl_in.length(); // ERROR
|
||||||
|
gl_in[1].gl_Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
in vec4 color[];
|
||||||
|
in vec4 color2[];
|
||||||
|
in vec4 colorS[3];
|
||||||
|
in vec4 colorBad[4];
|
||||||
|
|
||||||
|
void foo2()
|
||||||
|
{
|
||||||
|
color.length(); // ERROR
|
||||||
|
colorS.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(triangles) in; // give ERROR just for colorBad
|
||||||
|
|
||||||
|
in vec4 color[3];
|
||||||
|
in vec4 color2[3];
|
||||||
|
in vec4 colorbad2[2]; // ERROR
|
||||||
|
|
||||||
|
void foo3()
|
||||||
|
{
|
||||||
|
gl_in.length();
|
||||||
|
color.length();
|
||||||
|
color2.length();
|
||||||
|
colorS.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(location = 4) in vec4 cva[3];
|
||||||
|
layout(location = 5) in vec4 cvb[3];
|
||||||
|
layout(location = 2) in mat3 cmc[3]; // ERROR, collision
|
||||||
|
|
||||||
|
patch in vec4 patchIn[]; // ERROR
|
||||||
|
patch out vec4 patchOut; // ERROR
|
||||||
|
|
||||||
|
in float scalar; // ERROR, no array
|
||||||
|
|
||||||
|
layout(max_vertices = 127, invocations = 4) out; // ERROR
|
||||||
|
layout(invocations = 4, max_vertices = 127) in; // ERROR
|
||||||
|
layout(max_vertices = 127, invocations = 4) uniform; // 2 ERRORs
|
||||||
|
|
||||||
|
in inblockscalar {
|
||||||
|
int a;
|
||||||
|
} inbls; // ERROR, not an array
|
||||||
|
|
||||||
|
in inblocka {
|
||||||
|
int a;
|
||||||
|
} inbla[17]; // ERROR, wrong array size
|
||||||
|
|
||||||
|
void bits()
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(location = 7, index = 1) out vec4 indexedOut;
|
||||||
|
|
||||||
|
uniform sampler1D samp1D;
|
||||||
|
uniform sampler2DShadow samp2Ds;
|
||||||
|
|
||||||
|
void qlod()
|
||||||
|
{
|
||||||
|
vec2 lod;
|
||||||
|
float pf;
|
||||||
|
vec2 pf2;
|
||||||
|
vec3 pf3;
|
||||||
|
|
||||||
|
lod = textureQueryLod(samp1D, pf); // ERROR, only in fragment
|
||||||
|
lod = textureQueryLod(samp2Ds, pf2); // ERROR, only in fragment
|
||||||
|
}
|
||||||
|
|
||||||
|
void doubles()
|
||||||
|
{
|
||||||
|
double doublev;
|
||||||
|
dvec2 dvec2v;
|
||||||
|
dvec3 dvec3v;
|
||||||
|
dvec4 dvec4v;
|
||||||
|
|
||||||
|
bool boolv;
|
||||||
|
bvec2 bvec2v;
|
||||||
|
bvec3 bvec3v;
|
||||||
|
bvec4 bvec4v;
|
||||||
|
|
||||||
|
doublev = sqrt(2.9);
|
||||||
|
dvec2v = sqrt(dvec2(2.7));
|
||||||
|
dvec3v = sqrt(dvec3(2.0));
|
||||||
|
dvec4v = sqrt(dvec4(2.1));
|
||||||
|
|
||||||
|
doublev += inversesqrt(doublev);
|
||||||
|
dvec2v += inversesqrt(dvec2v);
|
||||||
|
dvec3v += inversesqrt(dvec3v);
|
||||||
|
dvec4v += inversesqrt(dvec4v);
|
||||||
|
|
||||||
|
doublev += abs(doublev);
|
||||||
|
dvec2v += abs(dvec2v);
|
||||||
|
dvec3v += abs(dvec3v);
|
||||||
|
dvec4v += abs(dvec4v);
|
||||||
|
|
||||||
|
doublev += sign(doublev);
|
||||||
|
dvec2v += sign(dvec2v);
|
||||||
|
dvec3v += sign(dvec3v);
|
||||||
|
dvec4v += sign(dvec4v);
|
||||||
|
|
||||||
|
doublev += floor(doublev);
|
||||||
|
dvec2v += floor(dvec2v);
|
||||||
|
dvec3v += floor(dvec3v);
|
||||||
|
dvec4v += floor(dvec4v);
|
||||||
|
|
||||||
|
doublev += trunc(doublev);
|
||||||
|
dvec2v += trunc(dvec2v);
|
||||||
|
dvec3v += trunc(dvec3v);
|
||||||
|
dvec4v += trunc(dvec4v);
|
||||||
|
|
||||||
|
doublev += round(doublev);
|
||||||
|
dvec2v += round(dvec2v);
|
||||||
|
dvec3v += round(dvec3v);
|
||||||
|
dvec4v += round(dvec4v);
|
||||||
|
|
||||||
|
doublev += roundEven(doublev);
|
||||||
|
dvec2v += roundEven(dvec2v);
|
||||||
|
dvec3v += roundEven(dvec3v);
|
||||||
|
dvec4v += roundEven(dvec4v);
|
||||||
|
|
||||||
|
doublev += ceil(doublev);
|
||||||
|
dvec2v += ceil(dvec2v);
|
||||||
|
dvec3v += ceil(dvec3v);
|
||||||
|
dvec4v += ceil(dvec4v);
|
||||||
|
|
||||||
|
doublev += fract(doublev);
|
||||||
|
dvec2v += fract(dvec2v);
|
||||||
|
dvec3v += fract(dvec3v);
|
||||||
|
dvec4v += fract(dvec4v);
|
||||||
|
|
||||||
|
doublev += mod(doublev, doublev);
|
||||||
|
dvec2v += mod(dvec2v, doublev);
|
||||||
|
dvec3v += mod(dvec3v, doublev);
|
||||||
|
dvec4v += mod(dvec4v, doublev);
|
||||||
|
dvec2v += mod(dvec2v, dvec2v);
|
||||||
|
dvec3v += mod(dvec3v, dvec3v);
|
||||||
|
dvec4v += mod(dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += modf(doublev, doublev);
|
||||||
|
dvec2v += modf(dvec2v, dvec2v);
|
||||||
|
dvec3v += modf(dvec3v, dvec3v);
|
||||||
|
dvec4v += modf(dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += min(doublev, doublev);
|
||||||
|
dvec2v += min(dvec2v, doublev);
|
||||||
|
dvec3v += min(dvec3v, doublev);
|
||||||
|
dvec4v += min(dvec4v, doublev);
|
||||||
|
dvec2v += min(dvec2v, dvec2v);
|
||||||
|
dvec3v += min(dvec3v, dvec3v);
|
||||||
|
dvec4v += min(dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += max(doublev, doublev);
|
||||||
|
dvec2v += max(dvec2v, doublev);
|
||||||
|
dvec3v += max(dvec3v, doublev);
|
||||||
|
dvec4v += max(dvec4v, doublev);
|
||||||
|
dvec2v += max(dvec2v, dvec2v);
|
||||||
|
dvec3v += max(dvec3v, dvec3v);
|
||||||
|
dvec4v += max(dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += clamp(doublev, doublev, doublev);
|
||||||
|
dvec2v += clamp(dvec2v, doublev, doublev);
|
||||||
|
dvec3v += clamp(dvec3v, doublev, doublev);
|
||||||
|
dvec4v += clamp(dvec4v, doublev, doublev);
|
||||||
|
dvec2v += clamp(dvec2v, dvec2v, dvec2v);
|
||||||
|
dvec3v += clamp(dvec3v, dvec3v, dvec3v);
|
||||||
|
dvec4v += clamp(dvec4v, dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += mix(doublev, doublev, doublev);
|
||||||
|
dvec2v += mix(dvec2v, dvec2v, doublev);
|
||||||
|
dvec3v += mix(dvec3v, dvec3v, doublev);
|
||||||
|
dvec4v += mix(dvec4v, dvec4v, doublev);
|
||||||
|
dvec2v += mix(dvec2v, dvec2v, dvec2v);
|
||||||
|
dvec3v += mix(dvec3v, dvec3v, dvec3v);
|
||||||
|
dvec4v += mix(dvec4v, dvec4v, dvec4v);
|
||||||
|
doublev += mix(doublev, doublev, boolv);
|
||||||
|
dvec2v += mix(dvec2v, dvec2v, bvec2v);
|
||||||
|
dvec3v += mix(dvec3v, dvec3v, bvec3v);
|
||||||
|
dvec4v += mix(dvec4v, dvec4v, bvec4v);
|
||||||
|
|
||||||
|
doublev += step(doublev, doublev);
|
||||||
|
dvec2v += step(dvec2v, dvec2v);
|
||||||
|
dvec3v += step(dvec3v, dvec3v);
|
||||||
|
dvec4v += step(dvec4v, dvec4v);
|
||||||
|
dvec2v += step(doublev, dvec2v);
|
||||||
|
dvec3v += step(doublev, dvec3v);
|
||||||
|
dvec4v += step(doublev, dvec4v);
|
||||||
|
|
||||||
|
doublev += smoothstep(doublev, doublev, doublev);
|
||||||
|
dvec2v += smoothstep(dvec2v, dvec2v, dvec2v);
|
||||||
|
dvec3v += smoothstep(dvec3v, dvec3v, dvec3v);
|
||||||
|
dvec4v += smoothstep(dvec4v, dvec4v, dvec4v);
|
||||||
|
dvec2v += smoothstep(doublev, doublev, dvec2v);
|
||||||
|
dvec3v += smoothstep(doublev, doublev, dvec3v);
|
||||||
|
dvec4v += smoothstep(doublev, doublev, dvec4v);
|
||||||
|
|
||||||
|
boolv = isnan(doublev);
|
||||||
|
bvec2v = isnan(dvec2v);
|
||||||
|
bvec3v = isnan(dvec3v);
|
||||||
|
bvec4v = isnan(dvec4v);
|
||||||
|
|
||||||
|
boolv = boolv ? isinf(doublev) : false;
|
||||||
|
bvec2v = boolv ? isinf(dvec2v) : bvec2(false);
|
||||||
|
bvec3v = boolv ? isinf(dvec3v) : bvec3(false);
|
||||||
|
bvec4v = boolv ? isinf(dvec4v) : bvec4(false);
|
||||||
|
|
||||||
|
doublev += length(doublev);
|
||||||
|
doublev += length(dvec2v);
|
||||||
|
doublev += length(dvec3v);
|
||||||
|
doublev += length(dvec4v);
|
||||||
|
|
||||||
|
doublev += distance(doublev, doublev);
|
||||||
|
doublev += distance(dvec2v, dvec2v);
|
||||||
|
doublev += distance(dvec3v, dvec3v);
|
||||||
|
doublev += distance(dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += dot(doublev, doublev);
|
||||||
|
doublev += dot(dvec2v, dvec2v);
|
||||||
|
doublev += dot(dvec3v, dvec3v);
|
||||||
|
doublev += dot(dvec4v, dvec4v);
|
||||||
|
|
||||||
|
dvec3v += cross(dvec3v, dvec3v);
|
||||||
|
|
||||||
|
doublev += normalize(doublev);
|
||||||
|
dvec2v += normalize(dvec2v);
|
||||||
|
dvec3v += normalize(dvec3v);
|
||||||
|
dvec4v += normalize(dvec4v);
|
||||||
|
|
||||||
|
doublev += faceforward(doublev, doublev, doublev);
|
||||||
|
dvec2v += faceforward(dvec2v, dvec2v, dvec2v);
|
||||||
|
dvec3v += faceforward(dvec3v, dvec3v, dvec3v);
|
||||||
|
dvec4v += faceforward(dvec4v, dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += reflect(doublev, doublev);
|
||||||
|
dvec2v += reflect(dvec2v, dvec2v);
|
||||||
|
dvec3v += reflect(dvec3v, dvec3v);
|
||||||
|
dvec4v += reflect(dvec4v, dvec4v);
|
||||||
|
|
||||||
|
doublev += refract(doublev, doublev, doublev);
|
||||||
|
dvec2v += refract(dvec2v, dvec2v, doublev);
|
||||||
|
dvec3v += refract(dvec3v, dvec3v, doublev);
|
||||||
|
dvec4v += refract(dvec4v, dvec4v, doublev);
|
||||||
|
|
||||||
|
dmat2 dmat2v = outerProduct(dvec2v, dvec2v);
|
||||||
|
dmat3 dmat3v = outerProduct(dvec3v, dvec3v);
|
||||||
|
dmat4 dmat4v = outerProduct(dvec4v, dvec4v);
|
||||||
|
dmat2x3 dmat2x3v = outerProduct(dvec3v, dvec2v);
|
||||||
|
dmat3x2 dmat3x2v = outerProduct(dvec2v, dvec3v);
|
||||||
|
dmat2x4 dmat2x4v = outerProduct(dvec4v, dvec2v);
|
||||||
|
dmat4x2 dmat4x2v = outerProduct(dvec2v, dvec4v);
|
||||||
|
dmat3x4 dmat3x4v = outerProduct(dvec4v, dvec3v);
|
||||||
|
dmat4x3 dmat4x3v = outerProduct(dvec3v, dvec4v);
|
||||||
|
|
||||||
|
dmat2v *= matrixCompMult(dmat2v, dmat2v);
|
||||||
|
dmat3v *= matrixCompMult(dmat3v, dmat3v);
|
||||||
|
dmat4v *= matrixCompMult(dmat4v, dmat4v);
|
||||||
|
dmat2x3v = matrixCompMult(dmat2x3v, dmat2x3v);
|
||||||
|
dmat2x4v = matrixCompMult(dmat2x4v, dmat2x4v);
|
||||||
|
dmat3x2v = matrixCompMult(dmat3x2v, dmat3x2v);
|
||||||
|
dmat3x4v = matrixCompMult(dmat3x4v, dmat3x4v);
|
||||||
|
dmat4x2v = matrixCompMult(dmat4x2v, dmat4x2v);
|
||||||
|
dmat4x3v = matrixCompMult(dmat4x3v, dmat4x3v);
|
||||||
|
|
||||||
|
dmat2v *= transpose(dmat2v);
|
||||||
|
dmat3v *= transpose(dmat3v);
|
||||||
|
dmat4v *= transpose(dmat4v);
|
||||||
|
dmat2x3v = transpose(dmat3x2v);
|
||||||
|
dmat3x2v = transpose(dmat2x3v);
|
||||||
|
dmat2x4v = transpose(dmat4x2v);
|
||||||
|
dmat4x2v = transpose(dmat2x4v);
|
||||||
|
dmat3x4v = transpose(dmat4x3v);
|
||||||
|
dmat4x3v = transpose(dmat3x4v);
|
||||||
|
|
||||||
|
doublev += determinant(dmat2v);
|
||||||
|
doublev += determinant(dmat3v);
|
||||||
|
doublev += determinant(dmat4v);
|
||||||
|
|
||||||
|
dmat2v *= inverse(dmat2v);
|
||||||
|
dmat3v *= inverse(dmat3v);
|
||||||
|
dmat4v *= inverse(dmat4v);
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
#version 400 core
|
||||||
|
|
||||||
|
layout(vertices = 4) 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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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
|
||||||
|
layout(vertices = 5) out; // ERROR
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
gl_out[4].gl_PointSize; // ERROR
|
||||||
|
|
||||||
|
barrier(); // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
in vec2 ina; // ERROR, not array
|
||||||
|
in vec2 inb[];
|
||||||
|
in vec2 inc[18]; // ERROR, wrong size
|
||||||
|
in vec2 ind[gl_MaxPatchVertices];
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
precise vec3 pv3;
|
||||||
|
|
||||||
|
void foop()
|
||||||
|
{
|
||||||
|
precise double d;
|
||||||
|
|
||||||
|
pv3 *= pv3;
|
||||||
|
pv3 = fma(pv3, pv3, pv3);
|
||||||
|
d = fma(d, d, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
patch out pinbn {
|
||||||
|
int a;
|
||||||
|
} pinbi;
|
||||||
|
|
||||||
|
invariant precise out vec4 badOrder[]; // ERROR, precise must appear first
|
||||||
|
void badp(out precise float f); // ERROR, precise must appear first
|
||||||
|
|
||||||
|
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_device_group
|
||||||
|
#extension GL_EXT_multiview : enable
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void devie()
|
||||||
|
{
|
||||||
|
gl_DeviceIndex;
|
||||||
|
gl_ViewIndex;
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
#version 400 core
|
||||||
|
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 // ERROR, no size
|
||||||
|
{
|
||||||
|
float gl_ClipDistance[1];
|
||||||
|
} gl_in[];
|
||||||
|
|
||||||
|
in gl_PerVertex // ERROR, second redeclaration of gl_in
|
||||||
|
{
|
||||||
|
float gl_ClipDistance[1];
|
||||||
|
} 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 {
|
||||||
|
int f;
|
||||||
|
} bla; // ERROR, not array
|
||||||
|
|
||||||
|
in testblb {
|
||||||
|
int f;
|
||||||
|
} blb[];
|
||||||
|
|
||||||
|
in testblc {
|
||||||
|
int f;
|
||||||
|
} blc[18]; // ERROR wrong size
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
layout(location = 23) out vec4 ovla[2];
|
||||||
|
layout(location = 24) out vec4 ovlb[2]; // ERROR
|
||||||
|
|
||||||
|
in float gl_TessLevelOuter[4]; // ERROR, can't redeclare
|
||||||
|
|
||||||
|
patch in pinbn {
|
||||||
|
int a;
|
||||||
|
} pinbi;
|
||||||
|
|
||||||
|
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_device_group
|
||||||
|
#extension GL_EXT_multiview : enable
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void devie()
|
||||||
|
{
|
||||||
|
gl_DeviceIndex;
|
||||||
|
gl_ViewIndex;
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
#version 400 core
|
||||||
|
|
||||||
|
in double d; // ERROR, no doubles
|
||||||
|
in dvec3 d3; // ERROR, no doubles
|
||||||
|
in dmat4 dm4; // ERROR, no doubles
|
||||||
|
|
||||||
|
// function selection under type conversion
|
||||||
|
void foo1(double a, uint b) {}
|
||||||
|
void foo1(double a, int b) {}
|
||||||
|
void foo1(double a, float b) {}
|
||||||
|
void foo1(double a, double b){}
|
||||||
|
|
||||||
|
void foo2(double a, float b) {}
|
||||||
|
void foo2(double a, double b){}
|
||||||
|
|
||||||
|
void foo3(double a, float b) {}
|
||||||
|
void foo3(float a, double b) {}
|
||||||
|
|
||||||
|
void ftd( int, float, double) {}
|
||||||
|
void ftd( uint, float, double) {}
|
||||||
|
void ftd(float, double, double) {}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
uint u;
|
||||||
|
int i;
|
||||||
|
float f;
|
||||||
|
|
||||||
|
foo1(d, d);
|
||||||
|
foo1(d, u);
|
||||||
|
foo1(d, i);
|
||||||
|
foo1(d, f);
|
||||||
|
|
||||||
|
foo1(f, d);
|
||||||
|
foo1(f, u);
|
||||||
|
foo1(f, i);
|
||||||
|
foo1(f, f);
|
||||||
|
|
||||||
|
foo1(u, d);
|
||||||
|
foo1(u, u);
|
||||||
|
foo1(u, i);
|
||||||
|
foo1(u, f);
|
||||||
|
|
||||||
|
foo1(i, d);
|
||||||
|
foo1(i, u);
|
||||||
|
foo1(i, i);
|
||||||
|
foo1(i, f);
|
||||||
|
|
||||||
|
foo2(d, d);
|
||||||
|
foo2(d, u);
|
||||||
|
foo2(d, i);
|
||||||
|
foo2(d, f);
|
||||||
|
|
||||||
|
foo2(f, d);
|
||||||
|
foo2(f, u);
|
||||||
|
foo2(f, i);
|
||||||
|
foo2(f, f);
|
||||||
|
|
||||||
|
foo2(u, d);
|
||||||
|
foo2(u, u);
|
||||||
|
foo2(u, i);
|
||||||
|
foo2(u, f);
|
||||||
|
|
||||||
|
foo2(i, d);
|
||||||
|
foo2(i, u);
|
||||||
|
foo2(i, i);
|
||||||
|
foo2(i, f);
|
||||||
|
|
||||||
|
foo3(d, d); // ERROR, no match
|
||||||
|
foo3(d, u);
|
||||||
|
foo3(d, i);
|
||||||
|
foo3(d, f);
|
||||||
|
|
||||||
|
foo3(f, d);
|
||||||
|
foo3(f, u); // ERROR, ambiguous
|
||||||
|
foo3(f, i); // ERROR, ambiguous
|
||||||
|
foo3(f, f); // ERROR, ambiguous
|
||||||
|
|
||||||
|
foo3(u, d);
|
||||||
|
foo3(u, u); // ERROR, ambiguous
|
||||||
|
foo3(u, i); // ERROR, ambiguous
|
||||||
|
foo3(u, f); // ERROR, ambiguous
|
||||||
|
|
||||||
|
foo3(i, d);
|
||||||
|
foo3(i, u); // ERROR, ambiguous
|
||||||
|
foo3(i, i); // ERROR, ambiguous
|
||||||
|
foo3(i, f); // ERROR, ambiguous
|
||||||
|
|
||||||
|
ftd(i, f, f);
|
||||||
|
ftd(u, f, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void itf(int, float, int);
|
||||||
|
void itf(int, double, int);
|
||||||
|
|
||||||
|
void tf()
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
uint u;
|
||||||
|
int i;
|
||||||
|
float f;
|
||||||
|
|
||||||
|
itf(i, i, i);
|
||||||
|
itf(i, u, i);
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#version 410 core
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_ViewportIndex = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
in gl_PerVertex {
|
||||||
|
float gl_PointSize;
|
||||||
|
} myIn[]; // ERROR, can't redeclare a different name
|
||||||
|
|
||||||
|
in gl_PerVertex {
|
||||||
|
float gl_PointSize;
|
||||||
|
} gl_myIn[]; // ERROR, can't redeclare a different name
|
||||||
|
|
||||||
|
in gl_PerVertex {
|
||||||
|
float gl_PointSize;
|
||||||
|
} gl_in[];
|
||||||
|
|
||||||
|
in gl_PerVertex {
|
||||||
|
float gl_PointSize;
|
||||||
|
} gl_in[]; // ERROR, can't do it again
|
||||||
|
|
||||||
|
out gl_PerVertex {
|
||||||
|
float gl_PointSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
float p = gl_in[1].gl_PointSize; // use of redeclared
|
||||||
|
gl_PointSize = p; // use of redeclared
|
||||||
|
vec4 v = gl_in[1].gl_Position; // ERROR, not included in the redeclaration
|
||||||
|
gl_Position = vec4(1.0); // ERROR, not included in the redeclaration
|
||||||
|
}
|
||||||
|
|
||||||
|
float foo5()
|
||||||
|
{
|
||||||
|
return 4; // implicit conversion of return type
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#version 400 core
|
||||||
|
|
||||||
|
// no layout(vertices = ...) out;
|
||||||
|
int outa[gl_out.length()]; // ERROR
|
||||||
|
|
||||||
|
patch out vec4 patchOut;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#version 410 core
|
||||||
|
|
||||||
|
in double d;
|
||||||
|
in dvec3 d3;
|
||||||
|
in dmat4 dm4;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#version 420
|
||||||
|
|
||||||
|
layout(local_size_x = 2) in; // ERROR, no compute
|
||||||
|
|
||||||
|
#extension GL_ARB_compute_shader : enable
|
||||||
|
|
||||||
|
layout(local_size_x = 2, local_size_y = 4, local_size_z = 6) in;
|
||||||
|
|
||||||
|
shared vec3 sfoo;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
sfoo = vec3(gl_WorkGroupSize.x, gl_WorkGroupSize.y, gl_WorkGroupSize.z);
|
||||||
|
sfoo += gl_WorkGroupSize + gl_NumWorkGroups + gl_WorkGroupID + gl_LocalInvocationID + gl_GlobalInvocationID;
|
||||||
|
sfoo *= gl_LocalInvocationIndex;
|
||||||
|
sfoo += gl_MaxComputeWorkGroupCount + gl_MaxComputeWorkGroupSize;
|
||||||
|
sfoo *= gl_MaxComputeUniformComponents +
|
||||||
|
gl_MaxComputeTextureImageUnits +
|
||||||
|
gl_MaxComputeImageUniforms +
|
||||||
|
gl_MaxComputeAtomicCounters +
|
||||||
|
gl_MaxComputeAtomicCounterBuffers;
|
||||||
|
|
||||||
|
barrier();
|
||||||
|
memoryBarrier();
|
||||||
|
memoryBarrierAtomicCounter();
|
||||||
|
memoryBarrierBuffer();
|
||||||
|
memoryBarrierImage();
|
||||||
|
memoryBarrierShared();
|
||||||
|
groupMemoryBarrier();
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#version 420 core
|
||||||
|
|
||||||
|
layout(depth_any) out float gl_FragDepth;
|
||||||
|
layout(depth_greater) out float gl_FragDepth; // ERROR: redeclaration with different qualifier
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragDepth = 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(depth_less) in float depth; // ERROR: depth_less only applies to gl_FragDepth
|
||||||
|
layout(depth_any) out float gl_FragDepth; // ERROR, done after use
|
||||||
|
|
||||||
|
layout(binding=0) uniform atomic_uint a[];
|
|
@ -0,0 +1,55 @@
|
||||||
|
#version 420 core
|
||||||
|
|
||||||
|
// testing input arrays without a gl_in[] block redeclaration, see 400.geom for with
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
gl_in.length(); // ERROR
|
||||||
|
gl_in[1].gl_Position;
|
||||||
|
gl_in[i].gl_Position; // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(triangles) in;
|
||||||
|
|
||||||
|
in vec4 color3[3];
|
||||||
|
|
||||||
|
void foo3()
|
||||||
|
{
|
||||||
|
gl_in.length();
|
||||||
|
gl_in[i].gl_Position;
|
||||||
|
color3.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform sampler2D s2D;
|
||||||
|
in vec2 coord[];
|
||||||
|
uniform vec4 v4;
|
||||||
|
|
||||||
|
void foo4()
|
||||||
|
{
|
||||||
|
const ivec2 offsets[5] =
|
||||||
|
{
|
||||||
|
ivec2(0,1),
|
||||||
|
ivec2(1,-2),
|
||||||
|
ivec2(0,3),
|
||||||
|
ivec2(-3,0),
|
||||||
|
ivec2(2,1)
|
||||||
|
};
|
||||||
|
|
||||||
|
vec4 v = textureGatherOffset(s2D, coord[0], offsets[i].xy);
|
||||||
|
|
||||||
|
offsets[i].xy = ivec2(3); // ERROR
|
||||||
|
v4.x = 3.2; // ERROR
|
||||||
|
v4.xy; // should have non-uniform type
|
||||||
|
}
|
||||||
|
|
||||||
|
out gl_PerVertex {
|
||||||
|
float gl_PointSize[1]; // ERROR, adding array
|
||||||
|
float gl_ClipDistance; // ERROR, removing array
|
||||||
|
};
|
||||||
|
|
||||||
|
float foo5()
|
||||||
|
{
|
||||||
|
return i; // implicit conversion of return type
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#version 420 core
|
||||||
|
|
||||||
|
#extension GL_ARB_separate_shader_objects : enable
|
||||||
|
|
||||||
|
layout(vertices = 4) out;
|
||||||
|
|
||||||
|
out gl_PerVertex {
|
||||||
|
vec4 gl_Position;
|
||||||
|
} gl_out[3]; // ERROR, wrong size
|
||||||
|
|
||||||
|
out int a[gl_out.length()];
|
||||||
|
out int outb[5]; // ERROR, wrong size
|
||||||
|
out int outc[];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
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; // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
out float outf; // ERROR, no array
|
||||||
|
|
||||||
|
layout (location = 0) in dmat2x4 vs_tcs_first[];
|
||||||
|
layout (location = 12) in dmat2x4 vs_tcs_last[];
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
if ((dmat2x4(dvec4(-0.625, -0.5, -0.375lf, -0.25), dvec4(-0.375, -0.25, -0.125, 0)) != vs_tcs_first[0]) ||
|
||||||
|
(dmat2x4(dvec4(0.375, 0.5, 0.625, 0.75), dvec4(0.625, 0.75, 0.875, -0.625)) != vs_tcs_last[0]))
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(vertices = 0) out; // ERROR, can't be 0
|
|
@ -0,0 +1,90 @@
|
||||||
|
#version 420 core
|
||||||
|
|
||||||
|
const mat2x2 a = mat2( vec2( 1.0, 0.0 ), vec2( 0.0, 1.0 ) );
|
||||||
|
mat2x2 b = { vec2( 1.0, 0.0 ), vec2( 0.0, 1.0 ) };
|
||||||
|
const mat2x2 c = { { 1.0, 0.0, }, { 0.0, 1.0 } };
|
||||||
|
|
||||||
|
float a2[2] = { 3.4, 4.2, 5.0 }; // illegal
|
||||||
|
vec2 b2 = { 1.0, 2.0, 3.0 }; // illegal
|
||||||
|
mat3x3 c2 = { vec3(0.0), vec3(1.0), vec3(2.0), vec3(3.0) }; // illegal
|
||||||
|
mat2x2 d = { 1.0, 0.0, 0.0, 1.0 }; // illegal, can't flatten nesting
|
||||||
|
|
||||||
|
struct {
|
||||||
|
float a;
|
||||||
|
int b;
|
||||||
|
} e = { 1.2, 2, };
|
||||||
|
|
||||||
|
struct {
|
||||||
|
float a;
|
||||||
|
int b;
|
||||||
|
} e2 = { 1, 3 }; // legal, first initializer is converted
|
||||||
|
|
||||||
|
struct {
|
||||||
|
float a;
|
||||||
|
int b;
|
||||||
|
} e3 = { 1.2, 2, 3 }; // illegal
|
||||||
|
|
||||||
|
int a3 = true; // illegal
|
||||||
|
vec4 b3[2] = { vec4(0.0), 1.0 }; // illegal
|
||||||
|
vec4 b4[2] = vec4[2](vec4(0.0), mat2x2(1.0)); // illegal
|
||||||
|
mat4x2 c3 = { vec3(0.0), vec3(1.0) }; // illegal
|
||||||
|
|
||||||
|
struct S1 {
|
||||||
|
vec4 a;
|
||||||
|
vec4 b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
float s;
|
||||||
|
float t;
|
||||||
|
} d2[] = { S1(vec4(0.0), vec4(1.1)) }; // illegal
|
||||||
|
|
||||||
|
float b5[] = { 3.4, 4.2, 5.0, 5.2, 1.1 };
|
||||||
|
|
||||||
|
struct S3 {
|
||||||
|
float f;
|
||||||
|
mat2x3 m23;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S4 {
|
||||||
|
uvec2 uv2;
|
||||||
|
S3 s[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Single1 { int f; };
|
||||||
|
Single1 single1 = { 10 };
|
||||||
|
|
||||||
|
struct Single2 { uvec2 v; };
|
||||||
|
Single2 single2 = { { 1, 2 } };
|
||||||
|
|
||||||
|
struct Single3 { Single1 s1; };
|
||||||
|
Single3 single3 = { { 3 } };
|
||||||
|
|
||||||
|
struct Single4 { Single2 s1; };
|
||||||
|
Single4 single4 = { { { 4u, 5u } } };
|
||||||
|
|
||||||
|
const S4 constructed = S4(uvec2(1, 2),
|
||||||
|
S3[2](S3(3.0, mat2x3(4.0)),
|
||||||
|
S3(5.0, mat2x3(6.0))));
|
||||||
|
|
||||||
|
const S4 curlybad1 = { {1, 2},
|
||||||
|
{ {3, {4.0, 0, 0.0}, {0.0, 4.0, 0.0 } }, // ERROR, the mat2x3 isn't isolated
|
||||||
|
{5.0, {6, 0.0, 0.0}, {0.0, 6.0, 0.0 } } } };
|
||||||
|
|
||||||
|
const S4 curlyInit = { {1, 2},
|
||||||
|
{ {3, { {4.0, 0, 0.0}, {0.0, 4.0, 0.0 } } },
|
||||||
|
{5.0, { {6, 0.0, 0.0}, {0.0, 6.0, 0.0 } } } } };
|
||||||
|
|
||||||
|
float vc1, vc2, vc3;
|
||||||
|
vec3 av3 = vec3(vc1, vc2, vc3);
|
||||||
|
vec3 bv3 = { vc1, vc2, vc3 };
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
memoryBarrier();
|
||||||
|
|
||||||
|
if (constructed == curlybad1)
|
||||||
|
;
|
||||||
|
if (constructed == curlyInit)
|
||||||
|
;
|
||||||
|
}
|
|
@ -0,0 +1,161 @@
|
||||||
|
#version 420 core
|
||||||
|
#version 420 core
|
||||||
|
varying vec2 v2; // ERROR, varying reserved
|
||||||
|
in vec4 bad[10];
|
||||||
|
highp in vec4 badorder;
|
||||||
|
out invariant vec4 badorder2;
|
||||||
|
in centroid vec4 badorder4; // ERROR, no centroid input to vertex stage
|
||||||
|
out flat vec4 badorder3;
|
||||||
|
void bar(in const float a);
|
||||||
|
void bar2(highp in float b);
|
||||||
|
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
|
||||||
|
|
||||||
|
int anonconst;
|
||||||
|
const int aconst = 5;
|
||||||
|
const int a = aconst;
|
||||||
|
const int b = anonconst; // ERROR at global scope
|
||||||
|
|
||||||
|
const int foo() // ERROR, no const functions
|
||||||
|
{
|
||||||
|
const int a = aconst;
|
||||||
|
const int b = anonconst;
|
||||||
|
const int c = a; // still compile-time const
|
||||||
|
const int d = b; // not a compile-time const
|
||||||
|
float x[c]; // okay
|
||||||
|
float y[d]; // ERROR
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (i == 3)
|
||||||
|
int j = i;
|
||||||
|
else
|
||||||
|
int k = j; // ERROR, j is undeclared
|
||||||
|
int m = k; // ERROR, k is undeclared
|
||||||
|
int n = j; // ERROR, j is undeclared
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
int jj;
|
||||||
|
int kk = jj; // ERROR, jj is undeclared
|
||||||
|
}
|
||||||
|
|
||||||
|
const float cx = 4.20;
|
||||||
|
const float dx = 4.20;
|
||||||
|
|
||||||
|
void bar(in highp volatile vec4 v)
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
s.x; // okay
|
||||||
|
s.y; // ERROR
|
||||||
|
if (bad[0].x == cx.x)
|
||||||
|
;
|
||||||
|
if (cx.x == dx.x)
|
||||||
|
badorder3 = bad[0];
|
||||||
|
|
||||||
|
float f;
|
||||||
|
vec3 smeared = f.xxx;
|
||||||
|
f.xxxxx; // ERROR
|
||||||
|
f.xxy; // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(binding = 3) uniform; // ERROR
|
||||||
|
layout(binding = 3) uniform boundblock { int aoeu; } boundInst;
|
||||||
|
layout(binding = 7) uniform anonblock { int aoeu; } ;
|
||||||
|
layout(location = 1) in; // ERROR
|
||||||
|
layout(binding = 1) in inblock { int aoeua; }; // ERROR
|
||||||
|
layout(binding = 100000) uniform anonblock2 { int aooeu; } ;
|
||||||
|
layout(binding = 4) uniform sampler2D sampb1;
|
||||||
|
layout(binding = 5) uniform sampler2D sampb2[10];
|
||||||
|
layout(binding = 80) uniform sampler2D sampb3; // ERROR, binding too big
|
||||||
|
layout(binding = 31) uniform sampler2D sampb4;
|
||||||
|
layout(binding = 79) uniform sampler2D sampb5[2]; // ERROR, binding too big
|
||||||
|
|
||||||
|
int fgfg(float f, mediump int i);
|
||||||
|
int fgfg(float f, highp int i);
|
||||||
|
|
||||||
|
out gl_PerVertex {
|
||||||
|
float gl_ClipDistance[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
patch in vec4 patchIn; // ERROR
|
||||||
|
patch out vec4 patchOut; // ERROR
|
||||||
|
|
||||||
|
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;
|
||||||
|
int a = gl_MinProgramTexelOffset + gl_MaxProgramTexelOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int comma0 = (2, 3); // ERROR
|
||||||
|
int comma1[(2, 3)]; // ERROR
|
||||||
|
|
||||||
|
layout(r32i) uniform iimage2D iimg2D;
|
||||||
|
layout(rgba32i) uniform iimage2D iimg2Drgba;
|
||||||
|
layout(rgba32f) uniform image2D img2Drgba;
|
||||||
|
layout(r32ui) uniform uimage2D uimg2D;
|
||||||
|
uniform image2DMS img2DMS; // ERROR image variables not declared writeonly must have format layout qualifier
|
||||||
|
uniform writeonly image2DMS img2DMSWO;
|
||||||
|
void qux()
|
||||||
|
{
|
||||||
|
int i = aoeu;
|
||||||
|
imageAtomicCompSwap(iimg2D, ivec2(i,i), i, i);
|
||||||
|
imageAtomicAdd(uimg2D, ivec2(i,i), uint(i));
|
||||||
|
imageAtomicMin(iimg2Drgba, ivec2(i,i), i); // ERROR iimg2Drgba does not have r32i layout
|
||||||
|
imageAtomicMax(img2Drgba, ivec2(i,i), i); // ERROR img2Drgba is not integer image
|
||||||
|
ivec4 pos = imageLoad(iimg2D, ivec2(i,i));
|
||||||
|
vec4 col = imageLoad(img2DMS, ivec2(i,i), i);
|
||||||
|
imageStore(img2DMSWO, ivec2(i,i), i, vec4(0));
|
||||||
|
imageLoad(img2DMSWO, ivec2(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 volatile readonly uniform iimage2D qualim2;
|
||||||
|
|
||||||
|
void passrc()
|
||||||
|
{
|
||||||
|
passr(qualim1);
|
||||||
|
passr(qualim2); // ERROR, drops volatile
|
||||||
|
passr(iimg2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(rg8i) uniform uimage2D i1bad; // ERROR, type mismatch
|
||||||
|
layout(rgba32i) uniform image2D i2bad; // ERROR, type mismatch
|
||||||
|
layout(rgba32f) uniform uimage2D i3bad; // ERROR, type mismatch
|
||||||
|
layout(r8_snorm) uniform iimage2D i4bad; // ERROR, type mismatch
|
||||||
|
layout(rgba32ui) uniform iimage2D i5bad; // ERROR, type mismatch
|
||||||
|
layout(r8ui) uniform iimage2D i6bad; // ERROR, type mismatch
|
||||||
|
|
||||||
|
uniform offcheck {
|
||||||
|
layout(offset = 16) int foo; // ERROR
|
||||||
|
} offcheckI;
|
||||||
|
|
||||||
|
uniform sampler1D samp1D;
|
||||||
|
uniform sampler1DShadow samp1Ds;
|
||||||
|
|
||||||
|
void qlod()
|
||||||
|
{
|
||||||
|
int levels;
|
||||||
|
|
||||||
|
levels = textureQueryLevels(samp1D); // ERROR, not until 430
|
||||||
|
levels = textureQueryLevels(samp1Ds); // ERROR, not until 430
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(binding=0) writeonly uniform image1D badArray[];
|
|
@ -0,0 +1,21 @@
|
||||||
|
#version 420 core
|
||||||
|
|
||||||
|
// testing input arrays without a gl_in[] block redeclaration, see 400.geom for with
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
layout(triangles) in;
|
||||||
|
in vec4 colorun[];
|
||||||
|
in vec4 color3[3];
|
||||||
|
|
||||||
|
void foo()
|
||||||
|
{
|
||||||
|
gl_in.length();
|
||||||
|
gl_in[1].gl_Position;
|
||||||
|
gl_in.length();
|
||||||
|
gl_in[i].gl_Position; // should be sized to 3 by 'triangles'
|
||||||
|
}
|
||||||
|
|
||||||
|
in gl_PerVertex { // ERROR, already used
|
||||||
|
vec4 gl_Position;
|
||||||
|
} gl_in[];
|
|
@ -0,0 +1,87 @@
|
||||||
|
#version 430 core
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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[];
|
||||||
|
int value;
|
||||||
|
} invalid;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
barrier();
|
||||||
|
memoryBarrier();
|
||||||
|
memoryBarrierAtomicCounter();
|
||||||
|
memoryBarrierBuffer();
|
||||||
|
memoryBarrierShared();
|
||||||
|
memoryBarrierImage();
|
||||||
|
groupMemoryBarrier();
|
||||||
|
value = int(values[gl_LocalInvocationIndex]);
|
||||||
|
|
||||||
|
int a;
|
||||||
|
if (a > 10)
|
||||||
|
barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
uniform double roll;
|
||||||
|
uniform writeonly image2D destTex;
|
||||||
|
void fooaoeu() {
|
||||||
|
ivec2 storePos = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
double localCoef = length(vec2(ivec2(gl_LocalInvocationID.xy)-8)/8.0);
|
||||||
|
dvec4 aa = dvec4(0.4, 0.2, 0.3, 0.4);
|
||||||
|
double globalCoef = 1.0;
|
||||||
|
int i = globalCoef; // ERROR, can't convert from double to int
|
||||||
|
double di = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
in inb { // ERROR
|
||||||
|
int a;
|
||||||
|
} inbi;
|
||||||
|
|
||||||
|
out outb { // ERROR
|
||||||
|
int a;
|
||||||
|
} outbi;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue