diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-04 14:17:57 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-01-05 10:05:06 +0000 |
commit | 39d357e3248f80abea0159765ff39554affb40db (patch) | |
tree | aba0e6bfb76de0244bba0f5fdbd64b830dd6e621 /chromium/third_party/angle/src | |
parent | 87778abf5a1f89266f37d1321b92a21851d8244d (diff) | |
download | qtwebengine-chromium-39d357e3248f80abea0159765ff39554affb40db.tar.gz |
BASELINE: Update Chromium to 55.0.2883.105
And updates ninja to 1.7.2
Change-Id: I20d43c737f82764d857ada9a55586901b18b9243
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/angle/src')
470 files changed, 41974 insertions, 22428 deletions
diff --git a/chromium/third_party/angle/src/angle.gyp b/chromium/third_party/angle/src/angle.gyp index 6496c2ff856..578f0f3526f 100644 --- a/chromium/third_party/angle/src/angle.gyp +++ b/chromium/third_party/angle/src/angle.gyp @@ -45,6 +45,7 @@ 'angle_enable_gl%': 1, }], ], + 'angle_enable_null%': 1, # Available on all platforms }, 'includes': [ @@ -143,6 +144,33 @@ }, { + 'target_name': 'angle_image_util', + 'type': 'static_library', + 'includes': [ '../build/common_defines.gypi', ], + 'sources': + [ + '<@(libangle_image_util_sources)', + ], + 'include_dirs': + [ + '.', + '../include', + ], + 'dependencies': + [ + 'angle_common', + ], + 'direct_dependent_settings': + { + 'include_dirs': + [ + '<(angle_path)/include', + '<(angle_path)/src', + ], + }, + }, + + { 'target_name': 'copy_scripts', 'type': 'none', 'includes': [ '../build/common_defines.gypi', ], diff --git a/chromium/third_party/angle/src/common/Color.h b/chromium/third_party/angle/src/common/Color.h new file mode 100644 index 00000000000..2b4d2f6fba4 --- /dev/null +++ b/chromium/third_party/angle/src/common/Color.h @@ -0,0 +1,53 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Color.h : Defines the Color type used throughout the ANGLE libraries + +#ifndef COMMON_COLOR_H_ +#define COMMON_COLOR_H_ + +namespace angle +{ + +template <typename T> +struct Color +{ + T red; + T green; + T blue; + T alpha; + + Color(); + Color(T r, T g, T b, T a); +}; + +template <typename T> +bool operator==(const Color<T> &a, const Color<T> &b); + +template <typename T> +bool operator!=(const Color<T> &a, const Color<T> &b); + +typedef Color<float> ColorF; +typedef Color<int> ColorI; +typedef Color<unsigned int> ColorUI; + +} // namespace angle + +// TODO: Move this fully into the angle namespace +namespace gl +{ + +template <typename T> +using Color = angle::Color<T>; +using ColorF = angle::ColorF; +using ColorI = angle::ColorI; +using ColorUI = angle::ColorUI; + +} // namespace gl + +#include "Color.inl" + +#endif // COMMON_COLOR_H_ diff --git a/chromium/third_party/angle/src/common/Color.inl b/chromium/third_party/angle/src/common/Color.inl new file mode 100644 index 00000000000..c3073256b58 --- /dev/null +++ b/chromium/third_party/angle/src/common/Color.inl @@ -0,0 +1,37 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Color.inl : Inline definitions of some functions from Color.h + +namespace angle +{ + +template <typename T> +Color<T>::Color() : Color(0, 0, 0, 0) +{ +} + +template <typename T> +Color<T>::Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a) +{ +} + +template <typename T> +bool operator==(const Color<T> &a, const Color<T> &b) +{ + return a.red == b.red && + a.green == b.green && + a.blue == b.blue && + a.alpha == b.alpha; +} + +template <typename T> +bool operator!=(const Color<T> &a, const Color<T> &b) +{ + return !(a == b); +} + +} // namespace angle diff --git a/chromium/third_party/angle/src/common/angleutils.h b/chromium/third_party/angle/src/common/angleutils.h index 948fd080ca5..f5ef7bdc13c 100644 --- a/chromium/third_party/angle/src/common/angleutils.h +++ b/chromium/third_party/angle/src/common/angleutils.h @@ -34,10 +34,10 @@ class NonCopyable }; extern const uintptr_t DirtyPointer; -} +} // namespace angle template <typename T, size_t N> -inline size_t ArraySize(T(&)[N]) +constexpr inline size_t ArraySize(T (&)[N]) { return N; } @@ -62,7 +62,7 @@ void SafeRelease(T& resource) } template <typename T> -void SafeDelete(T*& resource) +void SafeDelete(T *&resource) { delete resource; resource = NULL; @@ -156,11 +156,20 @@ size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char> std::string FormatString(const char *fmt, va_list vararg); std::string FormatString(const char *fmt, ...); +template <typename T> +std::string ToString(const T &value) +{ + std::ostringstream o; + o << value; + return o.str(); +} + // snprintf is not defined with MSVC prior to to msvc14 #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf #endif +#define GL_BGR565_ANGLEX 0x6ABB #define GL_BGRA4_ANGLEX 0x6ABC #define GL_BGR5_A1_ANGLEX 0x6ABD #define GL_INT_64_ANGLEX 0x6ABE diff --git a/chromium/third_party/angle/src/common/debug.h b/chromium/third_party/angle/src/common/debug.h index ccc80e80268..7424be5ef50 100644 --- a/chromium/third_party/angle/src/common/debug.h +++ b/chromium/third_party/angle/src/common/debug.h @@ -57,7 +57,7 @@ void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator); void UninitializeDebugAnnotations(); bool DebugAnnotationsActive(); -} +} // namespace gl #if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) #define ANGLE_TRACE_ENABLED @@ -104,24 +104,25 @@ bool DebugAnnotationsActive(); #undef ANGLE_TRACE_ENABLED #endif +#if defined(COMPILER_GCC) || __clang__ +#define ANGLE_CRASH() __builtin_trap() +#else +#define ANGLE_CRASH() ((void)(*(volatile char *)0 = 0)) +#endif + #if !defined(NDEBUG) #define ANGLE_ASSERT_IMPL(expression) assert(expression) #else // TODO(jmadill): Detect if debugger is attached and break. -#define ANGLE_ASSERT_IMPL(expression) abort() +#define ANGLE_ASSERT_IMPL(expression) ANGLE_CRASH() #endif // !defined(NDEBUG) // A macro asserting a condition and outputting failures to the debug log #if defined(ANGLE_ENABLE_ASSERTS) -#define ASSERT(expression) \ - { \ - if (!(expression)) \ - { \ - ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression); \ - ANGLE_ASSERT_IMPL(expression); \ - } \ - } \ - ANGLE_EMPTY_STATEMENT +#define ASSERT(expression) \ + (expression ? static_cast<void>(0) \ + : (ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression), \ + ANGLE_ASSERT_IMPL(expression))) #define UNUSED_ASSERTION_VARIABLE(variable) #else #define ASSERT(expression) (void(0)) @@ -136,29 +137,20 @@ bool DebugAnnotationsActive(); #define NOASSERT_UNIMPLEMENTED 1 #endif -// Define NOASSERT_UNIMPLEMENTED to non zero to skip the assert fail in the unimplemented checks // This will allow us to test with some automated test suites (eg dEQP) without crashing #ifndef NOASSERT_UNIMPLEMENTED #define NOASSERT_UNIMPLEMENTED 0 #endif -#if !defined(NDEBUG) -#define UNIMPLEMENTED() { \ - FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(NOASSERT_UNIMPLEMENTED); \ - } ANGLE_EMPTY_STATEMENT -#else - #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__) -#endif +#define UNIMPLEMENTED() \ + { \ + FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \ + ASSERT(NOASSERT_UNIMPLEMENTED); \ + } \ + ANGLE_EMPTY_STATEMENT // A macro for code which is not expected to be reached under valid assumptions -#if !defined(NDEBUG) -#define UNREACHABLE() { \ - ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(false); \ - } ANGLE_EMPTY_STATEMENT -#else - #define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__) -#endif +#define UNREACHABLE() \ + (ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__), ASSERT(false)) #endif // COMMON_DEBUG_H_ diff --git a/chromium/third_party/angle/src/common/mathutil.h b/chromium/third_party/angle/src/common/mathutil.h index 06421f07337..630b6c08878 100644 --- a/chromium/third_party/angle/src/common/mathutil.h +++ b/chromium/third_party/angle/src/common/mathutil.h @@ -44,6 +44,15 @@ struct Vector4 float w; }; +struct Vector2 +{ + Vector2() {} + Vector2(float x, float y) : x(x), y(y) {} + + float x; + float y; +}; + inline bool isPow2(int x) { return (x & (x - 1)) == 0 && (x != 0); @@ -135,7 +144,7 @@ inline unsigned int unorm(float x) inline bool supportsSSE2() { -#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) +#if defined(ANGLE_USE_SSE) static bool checked = false; static bool supports = false; @@ -144,21 +153,22 @@ inline bool supportsSSE2() return supports; } - int info[4]; - __cpuid(info, 0); - - if (info[0] >= 1) +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) { - __cpuid(info, 1); + int info[4]; + __cpuid(info, 0); - supports = (info[3] >> 26) & 1; - } + if (info[0] >= 1) + { + __cpuid(info, 1); + supports = (info[3] >> 26) & 1; + } + } +#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) checked = true; - return supports; -#else - UNIMPLEMENTED(); +#else // defined(ANGLE_USE_SSE) return false; #endif } @@ -755,6 +765,40 @@ constexpr unsigned int iSquareRoot() return priv::iSquareRoot<N, 1>::value; } +// Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow. +// +// Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow +// behavior is undefined. + +template <typename T> +inline T WrappingSum(T lhs, T rhs) +{ + uint32_t lhsUnsigned = static_cast<uint32_t>(lhs); + uint32_t rhsUnsigned = static_cast<uint32_t>(rhs); + return static_cast<T>(lhsUnsigned + rhsUnsigned); +} + +template <typename T> +inline T WrappingDiff(T lhs, T rhs) +{ + uint32_t lhsUnsigned = static_cast<uint32_t>(lhs); + uint32_t rhsUnsigned = static_cast<uint32_t>(rhs); + return static_cast<T>(lhsUnsigned - rhsUnsigned); +} + +inline int32_t WrappingMul(int32_t lhs, int32_t rhs) +{ + int64_t lhsWide = static_cast<int64_t>(lhs); + int64_t rhsWide = static_cast<int64_t>(rhs); + // The multiplication is guaranteed not to overflow. + int64_t resultWide = lhsWide * rhsWide; + // Implement the desired wrapping behavior by masking out the high-order 32 bits. + resultWide = resultWide & 0xffffffffll; + // Casting to a narrower signed type is fine since the casted value is representable in the + // narrower type. + return static_cast<int32_t>(resultWide); +} + } // namespace gl namespace rx @@ -798,8 +842,8 @@ inline uint16_t RotR16(uint16_t x, int8_t r) return (x >> r) | (x << (16 - r)); } -#define ANGLE_ROTL(x,y) RotL(x,y) -#define ANGLE_ROTR16(x,y) RotR16(x,y) +#define ANGLE_ROTL(x, y) ::rx::RotL(x, y) +#define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y) #endif // namespace rx diff --git a/chromium/third_party/angle/src/common/platform.h b/chromium/third_party/angle/src/common/platform.h index 56db297b715..15dac456c01 100644 --- a/chromium/third_party/angle/src/common/platform.h +++ b/chromium/third_party/angle/src/common/platform.h @@ -77,8 +77,16 @@ # undef far #endif -#if !defined(_M_ARM) && !defined(ANGLE_PLATFORM_ANDROID) -# define ANGLE_USE_SSE +#if defined(_MSC_VER) && !defined(_M_ARM) +#include <intrin.h> +#define ANGLE_USE_SSE +#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) +#include <x86intrin.h> +#define ANGLE_USE_SSE #endif +// The MemoryBarrier function name collides with a macro under Windows +// We will undef the macro so that the function name does not get replaced +#undef MemoryBarrier + #endif // COMMON_PLATFORM_H_ diff --git a/chromium/third_party/angle/src/common/string_utils.cpp b/chromium/third_party/angle/src/common/string_utils.cpp index 02bccd0209c..bb1edd245d2 100644 --- a/chromium/third_party/angle/src/common/string_utils.cpp +++ b/chromium/third_party/angle/src/common/string_utils.cpp @@ -9,8 +9,9 @@ #include "string_utils.h" +#include <algorithm> #include <stdlib.h> - +#include <string.h> #include <fstream> #include <sstream> @@ -157,4 +158,25 @@ Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString) return Optional<std::vector<wchar_t>>(wcstring); } +bool BeginsWith(const std::string &str, const char *prefix) +{ + return strncmp(str.c_str(), prefix, strlen(prefix)) == 0; +} + +bool BeginsWith(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)) == 0; +} + +bool EndsWith(const std::string &str, const char *suffix) +{ + const auto len = strlen(suffix); + if (len > str.size()) + return false; + + const char *end = str.c_str() + str.size() - len; + + return memcmp(end, suffix, len) == 0; +} + } // namespace angle diff --git a/chromium/third_party/angle/src/common/string_utils.h b/chromium/third_party/angle/src/common/string_utils.h index 99e7187de4e..c649c64d62a 100644 --- a/chromium/third_party/angle/src/common/string_utils.h +++ b/chromium/third_party/angle/src/common/string_utils.h @@ -47,6 +47,21 @@ bool HexStringToUInt(const std::string &input, unsigned int *uintOut); bool ReadFileToString(const std::string &path, std::string *stringOut); Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString); + +// Check if the string str begins with the given prefix. +// Prefix may not be NULL and needs to be NULL terminated. +// The comparison is case sensitive. +bool BeginsWith(const std::string &str, const char *prefix); + +// Check if the string str begins with the given prefix. +// str and prefix may not be NULL and need to be NULL terminated. +// The comparison is case sensitive. +bool BeginsWith(const char *str, const char *prefix); + +// Check if the string str ends with the given suffix. +// Suffix may not be NUL and needs to be NULL terminated. +// The comparison is case sensitive. +bool EndsWith(const std::string& str, const char* suffix); } #endif // LIBANGLE_STRING_UTILS_H_ diff --git a/chromium/third_party/angle/src/common/string_utils_unittest.cpp b/chromium/third_party/angle/src/common/string_utils_unittest.cpp index 1ab03d003a5..e7ce8a62de3 100644 --- a/chromium/third_party/angle/src/common/string_utils_unittest.cpp +++ b/chromium/third_party/angle/src/common/string_utils_unittest.cpp @@ -138,4 +138,26 @@ TEST(StringUtilsTest, HexStringToUIntBasic) // Note: ReadFileToString is harder to test + +TEST(StringUtilsTest, BeginsEndsWith) +{ + ASSERT_FALSE(BeginsWith("foo", "bar")); + ASSERT_FALSE(BeginsWith("", "foo")); + ASSERT_FALSE(BeginsWith("foo", "foobar")); + + ASSERT_TRUE(BeginsWith("foobar", "foo")); + ASSERT_TRUE(BeginsWith("foobar", "")); + ASSERT_TRUE(BeginsWith("foo", "foo")); + ASSERT_TRUE(BeginsWith("", "")); + + ASSERT_FALSE(EndsWith("foo", "bar")); + ASSERT_FALSE(EndsWith("", "bar")); + ASSERT_FALSE(EndsWith("foo", "foobar")); + + ASSERT_TRUE(EndsWith("foobar", "bar")); + ASSERT_TRUE(EndsWith("foobar", "")); + ASSERT_TRUE(EndsWith("bar", "bar")); + ASSERT_TRUE(EndsWith("", "")); } + +}
\ No newline at end of file diff --git a/chromium/third_party/angle/src/common/third_party/numerics/base/logging.h b/chromium/third_party/angle/src/common/third_party/numerics/base/logging.h index d4e3e240281..6cf05b4e6e0 100644 --- a/chromium/third_party/angle/src/common/third_party/numerics/base/logging.h +++ b/chromium/third_party/angle/src/common/third_party/numerics/base/logging.h @@ -16,7 +16,7 @@ // Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect. #ifndef NOTREACHED -#define NOTREACHED() 0 +#define NOTREACHED() UNREACHABLE() #endif -#endif // BASE_LOGGING_H_
\ No newline at end of file +#endif // BASE_LOGGING_H_ diff --git a/chromium/third_party/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h b/chromium/third_party/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h index 798465f5325..1591b9c8cba 100644 --- a/chromium/third_party/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h +++ b/chromium/third_party/angle/src/common/third_party/numerics/base/numerics/safe_conversions_impl.h @@ -92,7 +92,7 @@ struct StaticDstRangeRelationToSrcRange<Dst, static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED; }; -enum RangeConstraint +enum RangeConstraint : unsigned char { RANGE_VALID = 0x0, // Value can be represented by the destination type. RANGE_UNDERFLOW = 0x1, // Value would overflow. diff --git a/chromium/third_party/angle/src/compiler.gypi b/chromium/third_party/angle/src/compiler.gypi index feb8a0ee723..aed89913650 100644 --- a/chromium/third_party/angle/src/compiler.gypi +++ b/chromium/third_party/angle/src/compiler.gypi @@ -22,9 +22,13 @@ '../include/GLSLANG/ShaderVars.h', '../include/KHR/khrplatform.h', '../include/angle_gl.h', + 'compiler/translator/AddAndTrueToLoopCondition.cpp', + 'compiler/translator/AddAndTrueToLoopCondition.h', 'compiler/translator/BaseTypes.h', 'compiler/translator/BuiltInFunctionEmulator.cpp', 'compiler/translator/BuiltInFunctionEmulator.h', + 'compiler/translator/BreakVariableAliasingInInnerLoops.cpp', + 'compiler/translator/BreakVariableAliasingInInnerLoops.h', 'compiler/translator/Cache.cpp', 'compiler/translator/Cache.h', 'compiler/translator/CallDAG.cpp', @@ -33,6 +37,7 @@ 'compiler/translator/Common.h', 'compiler/translator/Compiler.cpp', 'compiler/translator/Compiler.h', + 'compiler/translator/ConstantUnion.cpp', 'compiler/translator/ConstantUnion.h', 'compiler/translator/DeferGlobalInitializers.cpp', 'compiler/translator/DeferGlobalInitializers.h', @@ -40,8 +45,12 @@ 'compiler/translator/Diagnostics.h', 'compiler/translator/DirectiveHandler.cpp', 'compiler/translator/DirectiveHandler.h', + 'compiler/translator/EmulateGLFragColorBroadcast.cpp', + 'compiler/translator/EmulateGLFragColorBroadcast.h', 'compiler/translator/EmulatePrecision.cpp', 'compiler/translator/EmulatePrecision.h', + 'compiler/translator/ExpandIntegerPowExpressions.cpp', + 'compiler/translator/ExpandIntegerPowExpressions.h', 'compiler/translator/ExtensionBehavior.h', 'compiler/translator/FlagStd140Structs.cpp', 'compiler/translator/FlagStd140Structs.h', @@ -77,6 +86,8 @@ 'compiler/translator/Pragma.h', 'compiler/translator/PruneEmptyDeclarations.cpp', 'compiler/translator/PruneEmptyDeclarations.h', + 'compiler/translator/QualifierTypes.h', + 'compiler/translator/QualifierTypes.cpp', 'compiler/translator/RecordConstantPrecision.cpp', 'compiler/translator/RecordConstantPrecision.h', 'compiler/translator/RegenerateStructNames.cpp', @@ -85,7 +96,10 @@ 'compiler/translator/RemovePow.h', 'compiler/translator/RewriteDoWhile.cpp', 'compiler/translator/RewriteDoWhile.h', - 'compiler/translator/RenameFunction.h', + 'compiler/translator/RewriteTexelFetchOffset.cpp', + 'compiler/translator/RewriteTexelFetchOffset.h', + 'compiler/translator/RewriteUnaryMinusOperatorInt.cpp', + 'compiler/translator/RewriteUnaryMinusOperatorInt.h', 'compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp', 'compiler/translator/ScalarizeVecAndMatConstructorArgs.h', 'compiler/translator/SearchSymbol.cpp', @@ -112,13 +126,6 @@ 'compiler/translator/VariablePacker.h', 'compiler/translator/blocklayout.cpp', 'compiler/translator/blocklayout.h', - 'compiler/translator/depgraph/DependencyGraph.cpp', - 'compiler/translator/depgraph/DependencyGraph.h', - 'compiler/translator/depgraph/DependencyGraphBuilder.cpp', - 'compiler/translator/depgraph/DependencyGraphBuilder.h', - 'compiler/translator/depgraph/DependencyGraphOutput.cpp', - 'compiler/translator/depgraph/DependencyGraphOutput.h', - 'compiler/translator/depgraph/DependencyGraphTraverse.cpp', 'compiler/translator/glslang.h', 'compiler/translator/glslang.l', 'compiler/translator/glslang.y', @@ -127,10 +134,6 @@ 'compiler/translator/glslang_tab.h', 'compiler/translator/intermOut.cpp', 'compiler/translator/length_limits.h', - 'compiler/translator/timing/RestrictFragmentShaderTiming.cpp', - 'compiler/translator/timing/RestrictFragmentShaderTiming.h', - 'compiler/translator/timing/RestrictVertexShaderTiming.cpp', - 'compiler/translator/timing/RestrictVertexShaderTiming.h', 'compiler/translator/util.cpp', 'compiler/translator/util.h', 'third_party/compiler/ArrayBoundsClamper.cpp', @@ -160,6 +163,8 @@ ], 'angle_translator_lib_hlsl_sources': [ + 'compiler/translator/AddDefaultReturnStatements.cpp', + 'compiler/translator/AddDefaultReturnStatements.h', 'compiler/translator/ArrayReturnValueToOutParameter.cpp', 'compiler/translator/ArrayReturnValueToOutParameter.h', 'compiler/translator/ASTMetadataHLSL.cpp', @@ -168,6 +173,8 @@ 'compiler/translator/blocklayoutHLSL.h', 'compiler/translator/BuiltInFunctionEmulatorHLSL.cpp', 'compiler/translator/BuiltInFunctionEmulatorHLSL.h', + 'compiler/translator/IntermNodePatternMatcher.cpp', + 'compiler/translator/IntermNodePatternMatcher.h', 'compiler/translator/OutputHLSL.cpp', 'compiler/translator/OutputHLSL.h', 'compiler/translator/RemoveDynamicIndexing.cpp', @@ -182,6 +189,10 @@ 'compiler/translator/SeparateDeclarations.h', 'compiler/translator/SeparateExpressionsReturningArrays.cpp', 'compiler/translator/SeparateExpressionsReturningArrays.h', + 'compiler/translator/SimplifyLoopConditions.cpp', + 'compiler/translator/SimplifyLoopConditions.h', + 'compiler/translator/SplitSequenceOperator.cpp', + 'compiler/translator/SplitSequenceOperator.h', 'compiler/translator/StructureHLSL.cpp', 'compiler/translator/StructureHLSL.h', 'compiler/translator/TextureFunctionHLSL.cpp', @@ -223,7 +234,6 @@ 'compiler/preprocessor/Tokenizer.h', 'compiler/preprocessor/Tokenizer.l', 'compiler/preprocessor/numeric_lex.h', - 'compiler/preprocessor/pp_utils.h', ], }, # Everything below this is duplicated in the GN build. If you change @@ -233,6 +243,7 @@ { 'target_name': 'preprocessor', 'type': 'static_library', + 'dependencies': [ 'angle_common' ], 'includes': [ '../build/common_defines.gypi', ], 'sources': [ '<@(angle_preprocessor_sources)', ], }, diff --git a/chromium/third_party/angle/src/compiler/fuzz/translator_fuzzer.cpp b/chromium/third_party/angle/src/compiler/fuzz/translator_fuzzer.cpp new file mode 100644 index 00000000000..5185522550e --- /dev/null +++ b/chromium/third_party/angle/src/compiler/fuzz/translator_fuzzer.cpp @@ -0,0 +1,162 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// translator_fuzzer.cpp: A libfuzzer fuzzer for the shader translator. + +#include <stddef.h> +#include <stdint.h> +#include <unordered_map> +#include <iostream> + +#include "compiler/translator/Compiler.h" +#include "angle_gl.h" + +struct TranslatorCacheKey +{ + bool operator==(const TranslatorCacheKey &other) const + { + return type == other.type && spec == other.spec && output == other.output; + } + + uint32_t type = 0; + uint32_t spec = 0; + uint32_t output = 0; +}; + +namespace std +{ + +template <> +struct hash<TranslatorCacheKey> +{ + std::size_t operator()(const TranslatorCacheKey &k) const + { + return (hash<uint32_t>()(k.type) << 1) ^ (hash<uint32_t>()(k.spec) >> 1) ^ + hash<uint32_t>()(k.output); + } +}; +} // namespace std + +static std::unordered_map<TranslatorCacheKey, TCompiler *> translators; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + // Reserve some size for future compile options + const size_t kHeaderSize = 128; + + if (size <= kHeaderSize) + { + return 0; + } + + // Make sure the rest of data will be a valid C string so that we don't have to copy it. + if (data[size - 1] != 0) + { + return 0; + } + + uint32_t type = *reinterpret_cast<const uint32_t *>(data); + uint32_t spec = *reinterpret_cast<const uint32_t *>(data + 4); + uint32_t output = *reinterpret_cast<const uint32_t *>(data + 8); + uint64_t options = *reinterpret_cast<const uint64_t *>(data + 12); + + if (type != GL_FRAGMENT_SHADER && type != GL_VERTEX_SHADER) + { + return 0; + } + + if (spec != SH_GLES2_SPEC && type != SH_WEBGL_SPEC && spec != SH_GLES3_SPEC && + spec != SH_WEBGL2_SPEC) + { + return 0; + } + + std::vector<uint32_t> validOutputs; + validOutputs.push_back(SH_ESSL_OUTPUT); + validOutputs.push_back(SH_GLSL_COMPATIBILITY_OUTPUT); + validOutputs.push_back(SH_GLSL_130_OUTPUT); + validOutputs.push_back(SH_GLSL_140_OUTPUT); + validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_410_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_420_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_430_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_440_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_450_CORE_OUTPUT); + validOutputs.push_back(SH_HLSL_OUTPUT); + validOutputs.push_back(SH_HLSL9_OUTPUT); + validOutputs.push_back(SH_HLSL11_OUTPUT); + validOutputs.push_back(SH_HLSL_3_0_OUTPUT); + validOutputs.push_back(SH_HLSL_4_1_OUTPUT); + validOutputs.push_back(SH_HLSL_4_0_FL9_3_OUTPUT); + bool found = false; + for (auto valid : validOutputs) + { + found = found || (valid == output); + } + if (!found) + { + return 0; + } + + size -= kHeaderSize; + data += kHeaderSize; + + if (!ShInitialize()) + { + return 0; + } + + TranslatorCacheKey key; + key.type = type; + key.spec = spec; + key.output = output; + + if (translators.find(key) == translators.end()) + { + TCompiler *translator = ConstructCompiler(type, static_cast<ShShaderSpec>(spec), + static_cast<ShShaderOutput>(output)); + + if (!translator) + { + return 0; + } + + ShBuiltInResources resources; + ShInitBuiltInResources(&resources); + + // Enable all the extensions to have more coverage + resources.OES_standard_derivatives = 1; + resources.OES_EGL_image_external = 1; + resources.OES_EGL_image_external_essl3 = 1; + resources.NV_EGL_stream_consumer_external = 1; + resources.ARB_texture_rectangle = 1; + resources.EXT_blend_func_extended = 1; + resources.EXT_draw_buffers = 1; + resources.EXT_frag_depth = 1; + resources.EXT_shader_texture_lod = 1; + resources.WEBGL_debug_shader_precision = 1; + resources.EXT_shader_framebuffer_fetch = 1; + resources.NV_shader_framebuffer_fetch = 1; + resources.ARM_shader_framebuffer_fetch = 1; + + if (!translator->Init(resources)) + { + DeleteCompiler(translator); + return 0; + } + + translators[key] = translator; + } + + TCompiler *translator = translators[key]; + + const char *shaderStrings[] = {reinterpret_cast<const char *>(data)}; + translator->compile(shaderStrings, 1, options); + + return 0; +} diff --git a/chromium/third_party/angle/src/compiler/preprocessor/64bit-tokenizer-safety.patch b/chromium/third_party/angle/src/compiler/preprocessor/64bit-tokenizer-safety.patch index 4c2f79441cc..912520c744b 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/64bit-tokenizer-safety.patch +++ b/chromium/third_party/angle/src/compiler/preprocessor/64bit-tokenizer-safety.patch @@ -1,31 +1,79 @@ +diff --git a/src/compiler/preprocessor/Tokenizer.cpp b/src/compiler/preprocessor/Tokenizer.cpp +index 0d7ad58..5ef0e5e 100644 --- a/src/compiler/preprocessor/Tokenizer.cpp +++ b/src/compiler/preprocessor/Tokenizer.cpp -@@ -56,6 +56,7 @@ typedef int16_t flex_int16_t; - typedef uint16_t flex_uint16_t; - typedef int32_t flex_int32_t; - typedef uint32_t flex_uint32_t; -+typedef uint64_t flex_uint64_t; - #else - typedef signed char flex_int8_t; - typedef short int flex_int16_t; -@@ -179,6 +180,11 @@ typedef void* yyscan_t; - typedef struct yy_buffer_state *YY_BUFFER_STATE; - #endif - -+#ifndef YY_TYPEDEF_YY_SIZE_T -+#define YY_TYPEDEF_YY_SIZE_T -+typedef size_t yy_size_t; -+#endif -+ - #define EOB_ACT_CONTINUE_SCAN 0 - #define EOB_ACT_END_OF_FILE 1 - #define EOB_ACT_LAST_MATCH 2 -@@ -353,7 +354,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); +@@ -1703,7 +1703,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) + else + { + int num_to_read = +- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; ++ static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1); + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +@@ -1737,8 +1737,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + +- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - +- number_to_move - 1; ++ num_to_read = static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - ++ number_to_move - 1); + + } + +@@ -1746,8 +1746,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ ++ yy_size_t ret = 0; + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- yyg->yy_n_chars, num_to_read ); ++ ret, num_to_read ); ++ yyg->yy_n_chars = static_cast<int>(ret); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } +@@ -1773,13 +1775,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner) + + if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ +- int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); ++ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + +- yyg->yy_n_chars += number_to_move; ++ yyg->yy_n_chars += static_cast<int>(number_to_move); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + +@@ -2171,7 +2173,7 @@ void pppop_buffer_state (yyscan_t yyscanner) */ - #define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ -- yyleng = (size_t) (yy_cp - yy_bp); \ -+ yyleng = (yy_size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; + static void ppensure_buffer_stack (yyscan_t yyscanner) + { +- int num_to_alloc; ++ yy_size_t num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { +@@ -2238,7 +2240,7 @@ YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" ); + +- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ ++ b->yy_buf_size = static_cast<int>(size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; +@@ -2293,7 +2295,7 @@ YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, int _yybytes_len , yysc + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" ); + +- for ( i = 0; i < _yybytes_len; ++i ) ++ for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp index 68c6e9cea48..fcb24e4e8d8 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.cpp @@ -4,9 +4,9 @@ // found in the LICENSE file. // -#include "DiagnosticsBase.h" +#include "compiler/preprocessor/DiagnosticsBase.h" -#include <cassert> +#include "common/debug.h" namespace pp { @@ -31,7 +31,7 @@ Diagnostics::Severity Diagnostics::severity(ID id) if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END)) return PP_WARNING; - assert(false); + UNREACHABLE(); return PP_ERROR; } @@ -74,6 +74,8 @@ std::string Diagnostics::message(ID id) return "predefined macro undefined"; case PP_MACRO_UNTERMINATED_INVOCATION: return "unterminated macro invocation"; + case PP_MACRO_UNDEFINED_WHILE_INVOKED: + return "macro undefined while being invoked"; case PP_MACRO_TOO_FEW_ARGS: return "Not enough arguments for macro"; case PP_MACRO_TOO_MANY_ARGS: @@ -115,6 +117,8 @@ std::string Diagnostics::message(ID id) return "invalid line directive"; case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3: return "extension directive must occur before any non-preprocessor tokens in ESSL3"; + case PP_UNDEFINED_SHIFT: + return "shift exponent is negative or undefined"; // Errors end. // Warnings begin. case PP_EOF_IN_DIRECTIVE: @@ -129,8 +133,8 @@ std::string Diagnostics::message(ID id) return "macro name with a double underscore is reserved - unintented behavior is possible"; // Warnings end. default: - assert(false); - return ""; + UNREACHABLE(); + return ""; } } diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h index d26c174f01c..6c3fe9ee92f 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/DiagnosticsBase.h @@ -44,6 +44,7 @@ class Diagnostics PP_MACRO_PREDEFINED_REDEFINED, PP_MACRO_PREDEFINED_UNDEFINED, PP_MACRO_UNTERMINATED_INVOCATION, + PP_MACRO_UNDEFINED_WHILE_INVOKED, PP_MACRO_TOO_FEW_ARGS, PP_MACRO_TOO_MANY_ARGS, PP_MACRO_DUPLICATE_PARAMETER_NAMES, @@ -65,6 +66,7 @@ class Diagnostics PP_INVALID_FILE_NUMBER, PP_INVALID_LINE_DIRECTIVE, PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3, + PP_UNDEFINED_SHIFT, PP_ERROR_END, PP_WARNING_BEGIN, diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp index ef35c6ed503..049dae9071c 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "DirectiveHandlerBase.h" +#include "compiler/preprocessor/DirectiveHandlerBase.h" namespace pp { diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp index 2faa3313781..643f73bd97a 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.cpp @@ -4,19 +4,19 @@ // found in the LICENSE file. // -#include "DirectiveParser.h" +#include "compiler/preprocessor/DirectiveParser.h" #include <algorithm> -#include <cassert> #include <cstdlib> #include <sstream> -#include "DiagnosticsBase.h" -#include "DirectiveHandlerBase.h" -#include "ExpressionParser.h" -#include "MacroExpander.h" -#include "Token.h" -#include "Tokenizer.h" +#include "common/debug.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/DirectiveHandlerBase.h" +#include "compiler/preprocessor/ExpressionParser.h" +#include "compiler/preprocessor/MacroExpander.h" +#include "compiler/preprocessor/Token.h" +#include "compiler/preprocessor/Tokenizer.h" namespace { enum DirectiveType @@ -118,8 +118,8 @@ void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) bool isMacroNameReserved(const std::string &name) { - // Names prefixed with "GL_" are reserved. - return (name.substr(0, 3) == "GL_"); + // Names prefixed with "GL_" and the name "defined" are reserved. + return name == "defined" || (name.substr(0, 3) == "GL_"); } bool hasDoubleUnderscores(const std::string &name) @@ -139,6 +139,66 @@ bool isMacroPredefined(const std::string &name, namespace pp { +class DefinedParser : public Lexer +{ + public: + DefinedParser(Lexer *lexer, const MacroSet *macroSet, Diagnostics *diagnostics) + : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics) + { + } + + protected: + void lex(Token *token) override + { + const char kDefined[] = "defined"; + + mLexer->lex(token); + if (token->type != Token::IDENTIFIER) + return; + if (token->text != kDefined) + return; + + bool paren = false; + mLexer->lex(token); + if (token->type == '(') + { + paren = true; + mLexer->lex(token); + } + + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); + skipUntilEOD(mLexer, token); + return; + } + MacroSet::const_iterator iter = mMacroSet->find(token->text); + std::string expression = iter != mMacroSet->end() ? "1" : "0"; + + if (paren) + { + mLexer->lex(token); + if (token->type != ')') + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + skipUntilEOD(mLexer, token); + return; + } + } + + // We have a valid defined operator. + // Convert the current token into a CONST_INT token. + token->type = Token::CONST_INT; + token->text = expression; + } + + private: + Lexer *mLexer; + const MacroSet *mMacroSet; + Diagnostics *mDiagnostics; +}; + DirectiveParser::DirectiveParser(Tokenizer *tokenizer, MacroSet *macroSet, Diagnostics *diagnostics, @@ -188,7 +248,7 @@ void DirectiveParser::lex(Token *token) void DirectiveParser::parseDirective(Token *token) { - assert(token->type == Token::PP_HASH); + ASSERT(token->type == Token::PP_HASH); mTokenizer->lex(token); if (isEOD(token)) @@ -254,8 +314,8 @@ void DirectiveParser::parseDirective(Token *token) parseLine(token); break; default: - assert(false); - break; + UNREACHABLE(); + break; } skipUntilEOD(mTokenizer, token); @@ -268,7 +328,7 @@ void DirectiveParser::parseDirective(Token *token) void DirectiveParser::parseDefine(Token *token) { - assert(getDirective(token) == DIRECTIVE_DEFINE); + ASSERT(getDirective(token) == DIRECTIVE_DEFINE); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) @@ -368,7 +428,7 @@ void DirectiveParser::parseDefine(Token *token) void DirectiveParser::parseUndef(Token *token) { - assert(getDirective(token) == DIRECTIVE_UNDEF); + ASSERT(getDirective(token) == DIRECTIVE_UNDEF); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) @@ -385,6 +445,13 @@ void DirectiveParser::parseUndef(Token *token) { mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, token->location, token->text); + return; + } + else if (iter->second.expansionCount > 0) + { + mDiagnostics->report(Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, token->location, + token->text); + return; } else { @@ -403,25 +470,25 @@ void DirectiveParser::parseUndef(Token *token) void DirectiveParser::parseIf(Token *token) { - assert(getDirective(token) == DIRECTIVE_IF); + ASSERT(getDirective(token) == DIRECTIVE_IF); parseConditionalIf(token); } void DirectiveParser::parseIfdef(Token *token) { - assert(getDirective(token) == DIRECTIVE_IFDEF); + ASSERT(getDirective(token) == DIRECTIVE_IFDEF); parseConditionalIf(token); } void DirectiveParser::parseIfndef(Token *token) { - assert(getDirective(token) == DIRECTIVE_IFNDEF); + ASSERT(getDirective(token) == DIRECTIVE_IFNDEF); parseConditionalIf(token); } void DirectiveParser::parseElse(Token *token) { - assert(getDirective(token) == DIRECTIVE_ELSE); + ASSERT(getDirective(token) == DIRECTIVE_ELSE); if (mConditionalStack.empty()) { @@ -462,7 +529,7 @@ void DirectiveParser::parseElse(Token *token) void DirectiveParser::parseElif(Token *token) { - assert(getDirective(token) == DIRECTIVE_ELIF); + ASSERT(getDirective(token) == DIRECTIVE_ELIF); if (mConditionalStack.empty()) { @@ -502,7 +569,7 @@ void DirectiveParser::parseElif(Token *token) void DirectiveParser::parseEndif(Token *token) { - assert(getDirective(token) == DIRECTIVE_ENDIF); + ASSERT(getDirective(token) == DIRECTIVE_ENDIF); if (mConditionalStack.empty()) { @@ -526,7 +593,7 @@ void DirectiveParser::parseEndif(Token *token) void DirectiveParser::parseError(Token *token) { - assert(getDirective(token) == DIRECTIVE_ERROR); + ASSERT(getDirective(token) == DIRECTIVE_ERROR); std::ostringstream stream; mTokenizer->lex(token); @@ -541,7 +608,7 @@ void DirectiveParser::parseError(Token *token) // Parses pragma of form: #pragma name[(value)]. void DirectiveParser::parsePragma(Token *token) { - assert(getDirective(token) == DIRECTIVE_PRAGMA); + ASSERT(getDirective(token) == DIRECTIVE_PRAGMA); enum State { @@ -602,7 +669,7 @@ void DirectiveParser::parsePragma(Token *token) void DirectiveParser::parseExtension(Token *token) { - assert(getDirective(token) == DIRECTIVE_EXTENSION); + ASSERT(getDirective(token) == DIRECTIVE_EXTENSION); enum State { @@ -683,7 +750,7 @@ void DirectiveParser::parseExtension(Token *token) void DirectiveParser::parseVersion(Token *token) { - assert(getDirective(token) == DIRECTIVE_VERSION); + ASSERT(getDirective(token) == DIRECTIVE_VERSION); if (mPastFirstStatement) { @@ -770,13 +837,13 @@ void DirectiveParser::parseVersion(Token *token) void DirectiveParser::parseLine(Token *token) { - assert(getDirective(token) == DIRECTIVE_LINE); + ASSERT(getDirective(token) == DIRECTIVE_LINE); bool valid = true; bool parsedFileNumber = false; int line = 0, file = 0; - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false); + MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics); // Lex the first token after "#line" so we can check it for EOD. macroExpander.lex(token); @@ -871,8 +938,8 @@ void DirectiveParser::parseConditionalIf(Token *token) expression = parseExpressionIfdef(token) == 0 ? 1 : 0; break; default: - assert(false); - break; + UNREACHABLE(); + break; } block.skipGroup = expression == 0; block.foundValidGroup = expression != 0; @@ -882,10 +949,10 @@ void DirectiveParser::parseConditionalIf(Token *token) int DirectiveParser::parseExpressionIf(Token *token) { - assert((getDirective(token) == DIRECTIVE_IF) || - (getDirective(token) == DIRECTIVE_ELIF)); + ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true); + DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics); + MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics); ExpressionParser expressionParser(¯oExpander, mDiagnostics); int expression = 0; @@ -909,8 +976,7 @@ int DirectiveParser::parseExpressionIf(Token *token) int DirectiveParser::parseExpressionIfdef(Token *token) { - assert((getDirective(token) == DIRECTIVE_IFDEF) || - (getDirective(token) == DIRECTIVE_IFNDEF)); + ASSERT((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF)); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) diff --git a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h index 2888e289cee..f0e889c8a08 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/DirectiveParser.h @@ -7,10 +7,9 @@ #ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_ #define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_ -#include "Lexer.h" -#include "Macro.h" -#include "pp_utils.h" -#include "SourceLocation.h" +#include "compiler/preprocessor/Lexer.h" +#include "compiler/preprocessor/Macro.h" +#include "compiler/preprocessor/SourceLocation.h" namespace pp { @@ -30,7 +29,6 @@ class DirectiveParser : public Lexer void lex(Token *token) override; private: - PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser); void parseDirective(Token *token); void parseDefine(Token *token); diff --git a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp index 193b150134c..f737a2e7a0d 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.cpp @@ -99,17 +99,15 @@ #include <cassert> #include <sstream> +#include <stdint.h> #include "DiagnosticsBase.h" #include "Lexer.h" #include "Token.h" +#include "common/mathutil.h" -#if defined(_MSC_VER) -typedef __int64 YYSTYPE; -#else -#include <stdint.h> -typedef intmax_t YYSTYPE; -#endif // _MSC_VER +typedef int32_t YYSTYPE; +typedef uint32_t UNSIGNED_TYPE; #define YYENABLE_NLS 0 #define YYLTYPE_IS_TRIVIAL 1 @@ -500,9 +498,9 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 110, 110, 117, 118, 129, 129, 150, 150, 171, - 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, - 204, 207, 210, 230, 250, 253, 256, 259, 262, 265 + 0, 108, 108, 115, 116, 127, 127, 148, 148, 169, + 172, 175, 178, 181, 184, 187, 190, 193, 196, 221, + 246, 249, 252, 272, 299, 302, 305, 308, 320, 323 }; #endif @@ -1495,7 +1493,29 @@ yyreduce: case 18: { - (yyval) = (yyvsp[-2]) >> (yyvsp[0]); + if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << (yyvsp[-2]) << " >> " << (yyvsp[0]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + (yyval) = static_cast<YYSTYPE>(0); + } + else if ((yyvsp[-2]) < 0) + { + // Logical shift right. + (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) >> (yyvsp[0])); + } + else + { + (yyval) = (yyvsp[-2]) >> (yyvsp[0]); + } } break; @@ -1503,7 +1523,29 @@ yyreduce: case 19: { - (yyval) = (yyvsp[-2]) << (yyvsp[0]); + if ((yyvsp[0]) < 0 || (yyvsp[0]) > 31) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << (yyvsp[-2]) << " << " << (yyvsp[0]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + (yyval) = static_cast<YYSTYPE>(0); + } + else if ((yyvsp[-2]) < 0) + { + // Logical shift left. + (yyval) = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>((yyvsp[-2])) << (yyvsp[0])); + } + else + { + (yyval) = (yyvsp[-2]) << (yyvsp[0]); + } } break; @@ -1511,7 +1553,7 @@ yyreduce: case 20: { - (yyval) = (yyvsp[-2]) - (yyvsp[0]); + (yyval) = gl::WrappingDiff<YYSTYPE>((yyvsp[-2]), (yyvsp[0])); } break; @@ -1519,7 +1561,7 @@ yyreduce: case 21: { - (yyval) = (yyvsp[-2]) + (yyvsp[0]); + (yyval) = gl::WrappingSum<YYSTYPE>((yyvsp[-2]), (yyvsp[0])); } break; @@ -1566,6 +1608,13 @@ yyreduce: } (yyval) = static_cast<YYSTYPE>(0); } + else if ((yyvsp[-2]) == std::numeric_limits<YYSTYPE>::min() && (yyvsp[0]) == -1) + { + // Check for the special case where the minimum representable number is + // divided by -1. If left alone this leads to integer overflow in C++, which + // has undefined results. + (yyval) = std::numeric_limits<YYSTYPE>::max(); + } else { (yyval) = (yyvsp[-2]) / (yyvsp[0]); @@ -1577,7 +1626,7 @@ yyreduce: case 24: { - (yyval) = (yyvsp[-2]) * (yyvsp[0]); + (yyval) = gl::WrappingMul((yyvsp[-2]), (yyvsp[0])); } break; @@ -1601,7 +1650,16 @@ yyreduce: case 27: { - (yyval) = - (yyvsp[0]); + // Check for negation of minimum representable integer to prevent undefined signed int + // overflow. + if ((yyvsp[0]) == std::numeric_limits<YYSTYPE>::min()) + { + (yyval) = std::numeric_limits<YYSTYPE>::min(); + } + else + { + (yyval) = -(yyvsp[0]); + } } break; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h index 841c67b61cd..0f2901b8786 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.h @@ -7,8 +7,8 @@ #ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ #define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ -#include "DiagnosticsBase.h" -#include "pp_utils.h" +#include "common/angleutils.h" +#include "compiler/preprocessor/DiagnosticsBase.h" namespace pp { @@ -16,7 +16,7 @@ namespace pp class Lexer; struct Token; -class ExpressionParser +class ExpressionParser : angle::NonCopyable { public: struct ErrorSettings @@ -34,8 +34,6 @@ class ExpressionParser bool *valid); private: - PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser); - Lexer *mLexer; Diagnostics *mDiagnostics; }; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y index 7b5d9e9cee9..a98638a8df8 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y +++ b/chromium/third_party/angle/src/compiler/preprocessor/ExpressionParser.y @@ -41,17 +41,15 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser. #include <cassert> #include <sstream> +#include <stdint.h> #include "DiagnosticsBase.h" #include "Lexer.h" #include "Token.h" +#include "common/mathutil.h" -#if defined(_MSC_VER) -typedef __int64 YYSTYPE; -#else -#include <stdint.h> -typedef intmax_t YYSTYPE; -#endif // _MSC_VER +typedef int32_t YYSTYPE; +typedef uint32_t UNSIGNED_TYPE; #define YYENABLE_NLS 0 #define YYLTYPE_IS_TRIVIAL 1 @@ -196,16 +194,60 @@ expression $$ = $1 < $3; } | expression TOK_OP_RIGHT expression { - $$ = $1 >> $3; + if ($3 < 0 || $3 > 31) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " >> " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast<YYSTYPE>(0); + } + else if ($1 < 0) + { + // Logical shift right. + $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) >> $3); + } + else + { + $$ = $1 >> $3; + } } | expression TOK_OP_LEFT expression { - $$ = $1 << $3; + if ($3 < 0 || $3 > 31) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " << " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast<YYSTYPE>(0); + } + else if ($1 < 0) + { + // Logical shift left. + $$ = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>($1) << $3); + } + else + { + $$ = $1 << $3; + } } | expression '-' expression { - $$ = $1 - $3; + $$ = gl::WrappingDiff<YYSTYPE>($1, $3); } | expression '+' expression { - $$ = $1 + $3; + $$ = gl::WrappingSum<YYSTYPE>($1, $3); } | expression '%' expression { if ($3 == 0) @@ -242,13 +284,20 @@ expression } $$ = static_cast<YYSTYPE>(0); } + else if ($1 == std::numeric_limits<YYSTYPE>::min() && $3 == -1) + { + // Check for the special case where the minimum representable number is + // divided by -1. If left alone this leads to integer overflow in C++, which + // has undefined results. + $$ = std::numeric_limits<YYSTYPE>::max(); + } else { $$ = $1 / $3; } } | expression '*' expression { - $$ = $1 * $3; + $$ = gl::WrappingMul($1, $3); } | '!' expression %prec TOK_UNARY { $$ = ! $2; @@ -257,7 +306,16 @@ expression $$ = ~ $2; } | '-' expression %prec TOK_UNARY { - $$ = - $2; + // Check for negation of minimum representable integer to prevent undefined signed int + // overflow. + if ($2 == std::numeric_limits<YYSTYPE>::min()) + { + $$ = std::numeric_limits<YYSTYPE>::min(); + } + else + { + $$ = -$2; + } } | '+' expression %prec TOK_UNARY { $$ = + $2; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp index 5541d46f729..8bce56ff29a 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Input.cpp @@ -4,12 +4,13 @@ // found in the LICENSE file. // -#include "Input.h" +#include "compiler/preprocessor/Input.h" #include <algorithm> -#include <cassert> #include <cstring> +#include "common/debug.h" + namespace pp { @@ -32,7 +33,7 @@ Input::Input(size_t count, const char *const string[], const int length[]) : const char *Input::skipChar() { // This function should only be called when there is a character to skip. - assert(mReadLoc.cIndex < mLength[mReadLoc.sIndex]); + ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]); ++mReadLoc.cIndex; if (mReadLoc.cIndex == mLength[mReadLoc.sIndex]) { diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Input.h b/chromium/third_party/angle/src/compiler/preprocessor/Input.h index a1de7ddd86b..ecbb04962df 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Input.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Input.h @@ -7,7 +7,7 @@ #ifndef COMPILER_PREPROCESSOR_INPUT_H_ #define COMPILER_PREPROCESSOR_INPUT_H_ -#include <stddef.h> +#include <cstddef> #include <vector> namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Lexer.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Lexer.cpp index 7c663ee7617..89cb3cf44e4 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Lexer.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Lexer.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "Lexer.h" +#include "compiler/preprocessor/Lexer.h" namespace pp { diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h b/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h index 990dc5e21de..775bc0a202a 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Lexer.h @@ -7,12 +7,14 @@ #ifndef COMPILER_PREPROCESSOR_LEXER_H_ #define COMPILER_PREPROCESSOR_LEXER_H_ +#include "common/angleutils.h" + namespace pp { struct Token; -class Lexer +class Lexer : angle::NonCopyable { public: virtual ~Lexer(); diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp index 4c4d5fd2e29..f5c94399db7 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Macro.cpp @@ -4,11 +4,10 @@ // found in the LICENSE file. // -#include "Macro.h" +#include "compiler/preprocessor/Macro.h" -#include <sstream> - -#include "Token.h" +#include "common/angleutils.h" +#include "compiler/preprocessor/Token.h" namespace pp { @@ -23,12 +22,9 @@ bool Macro::equals(const Macro &other) const void PredefineMacro(MacroSet *macroSet, const char *name, int value) { - std::ostringstream stream; - stream << value; - Token token; token.type = Token::CONST_INT; - token.text = stream.str(); + token.text = ToString(value); Macro macro; macro.predefined = true; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Macro.h b/chromium/third_party/angle/src/compiler/preprocessor/Macro.h index 31ee22c26a2..557df163c20 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Macro.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Macro.h @@ -26,16 +26,12 @@ struct Macro typedef std::vector<std::string> Parameters; typedef std::vector<Token> Replacements; - Macro() - : predefined(false), - disabled(false), - type(kTypeObj) - { - } + Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj) {} bool equals(const Macro &other) const; bool predefined; mutable bool disabled; + mutable int expansionCount; Type type; std::string name; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp index e878ee345a6..f38b3963515 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.cpp @@ -4,17 +4,22 @@ // found in the LICENSE file. // -#include "MacroExpander.h" +#include "compiler/preprocessor/MacroExpander.h" #include <algorithm> -#include <sstream> -#include "DiagnosticsBase.h" -#include "Token.h" +#include "common/debug.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/Token.h" namespace pp { +namespace +{ + +const size_t kMaxContextTokens = 10000; + class TokenLexer : public Lexer { public: @@ -40,25 +45,22 @@ class TokenLexer : public Lexer } private: - PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer); - TokenVector mTokens; TokenVector::const_iterator mIter; }; -MacroExpander::MacroExpander(Lexer *lexer, - MacroSet *macroSet, - Diagnostics *diagnostics, - bool parseDefined) - : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mParseDefined(parseDefined) +} // anonymous namespace + +MacroExpander::MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics) + : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mTotalTokensInContexts(0) { } MacroExpander::~MacroExpander() { - for (std::size_t i = 0; i < mContextStack.size(); ++i) + for (MacroContext *context : mContextStack) { - delete mContextStack[i]; + delete context; } } @@ -66,54 +68,11 @@ void MacroExpander::lex(Token *token) { while (true) { - const char kDefined[] = "defined"; - getToken(token); if (token->type != Token::IDENTIFIER) break; - // Defined operator is parsed here since it may be generated by macro expansion. - // Defined operator produced by macro expansion has undefined behavior according to C++ - // spec, which the GLSL spec references (see C++14 draft spec section 16.1.4), but this - // behavior is needed for passing dEQP tests, which enforce stricter compatibility between - // implementations. - if (mParseDefined && token->text == kDefined) - { - bool paren = false; - getToken(token); - if (token->type == '(') - { - paren = true; - getToken(token); - } - if (token->type != Token::IDENTIFIER) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, - token->text); - break; - } - auto iter = mMacroSet->find(token->text); - std::string expression = iter != mMacroSet->end() ? "1" : "0"; - - if (paren) - { - getToken(token); - if (token->type != ')') - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, - token->text); - break; - } - } - - // We have a valid defined operator. - // Convert the current token into a CONST_INT token. - token->type = Token::CONST_INT; - token->text = expression; - break; - } - if (token->expansionDisabled()) break; @@ -160,6 +119,7 @@ void MacroExpander::getToken(Token *token) } else { + ASSERT(mTotalTokensInContexts == 0); mLexer->lex(token); } } @@ -170,11 +130,11 @@ void MacroExpander::ungetToken(const Token &token) { MacroContext *context = mContextStack.back(); context->unget(); - assert(context->replacements[context->index] == token); + ASSERT(context->replacements[context->index] == token); } else { - assert(!mReserveToken.get()); + ASSERT(!mReserveToken.get()); mReserveToken.reset(new Token(token)); } } @@ -192,10 +152,12 @@ bool MacroExpander::isNextTokenLeftParen() bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier) { - assert(!macro.disabled); - assert(!identifier.expansionDisabled()); - assert(identifier.type == Token::IDENTIFIER); - assert(identifier.text == macro.name); + ASSERT(!macro.disabled); + ASSERT(!identifier.expansionDisabled()); + ASSERT(identifier.type == Token::IDENTIFIER); + ASSERT(identifier.text == macro.name); + + macro.expansionCount++; std::vector<Token> replacements; if (!expandMacro(macro, identifier, &replacements)) @@ -208,19 +170,23 @@ bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier) context->macro = ¯o; context->replacements.swap(replacements); mContextStack.push_back(context); + mTotalTokensInContexts += context->replacements.size(); return true; } void MacroExpander::popMacro() { - assert(!mContextStack.empty()); + ASSERT(!mContextStack.empty()); MacroContext *context = mContextStack.back(); mContextStack.pop_back(); - assert(context->empty()); - assert(context->macro->disabled); + ASSERT(context->empty()); + ASSERT(context->macro->disabled); + ASSERT(context->macro->expansionCount > 0); context->macro->disabled = false; + context->macro->expansionCount--; + mTotalTokensInContexts -= context->replacements.size(); delete context; } @@ -245,25 +211,21 @@ bool MacroExpander::expandMacro(const Macro ¯o, const char kLine[] = "__LINE__"; const char kFile[] = "__FILE__"; - assert(replacements->size() == 1); + ASSERT(replacements->size() == 1); Token& repl = replacements->front(); if (macro.name == kLine) { - std::ostringstream stream; - stream << identifier.location.line; - repl.text = stream.str(); + repl.text = ToString(identifier.location.line); } else if (macro.name == kFile) { - std::ostringstream stream; - stream << identifier.location.file; - repl.text = stream.str(); + repl.text = ToString(identifier.location.file); } } } else { - assert(macro.type == Macro::kTypeFunc); + ASSERT(macro.type == Macro::kTypeFunc); std::vector<MacroArg> args; args.reserve(macro.parameters.size()); if (!collectMacroArgs(macro, identifier, &args, &replacementLocation)) @@ -294,10 +256,12 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, { Token token; getToken(&token); - assert(token.type == '('); + ASSERT(token.type == '('); args->push_back(MacroArg()); - for (int openParens = 1; openParens != 0; ) + + int openParens = 1; + while (openParens != 0) { getToken(&token); @@ -363,11 +327,11 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, // Pre-expand each argument before substitution. // This step expands each argument individually before they are // inserted into the macro body. - for (std::size_t i = 0; i < args->size(); ++i) + size_t numTokens = 0; + for (auto &arg : *args) { - MacroArg &arg = args->at(i); TokenLexer lexer(&arg); - MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined); + MacroExpander expander(&lexer, mMacroSet, mDiagnostics); arg.clear(); expander.lex(&token); @@ -375,6 +339,12 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, { arg.push_back(token); expander.lex(&token); + numTokens++; + if (numTokens + mTotalTokensInContexts > kMaxContextTokens) + { + mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text); + return false; + } } } return true; @@ -386,6 +356,14 @@ void MacroExpander::replaceMacroParams(const Macro ¯o, { for (std::size_t i = 0; i < macro.replacements.size(); ++i) { + if (!replacements->empty() && + replacements->size() + mTotalTokensInContexts > kMaxContextTokens) + { + const Token &token = replacements->back(); + mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text); + return; + } + const Token &repl = macro.replacements[i]; if (repl.type != Token::IDENTIFIER) { @@ -418,5 +396,25 @@ void MacroExpander::replaceMacroParams(const Macro ¯o, } } +MacroExpander::MacroContext::MacroContext() : macro(0), index(0) +{ +} + +bool MacroExpander::MacroContext::empty() const +{ + return index == replacements.size(); +} + +const Token &MacroExpander::MacroContext::get() +{ + return replacements[index++]; +} + +void MacroExpander::MacroContext::unget() +{ + ASSERT(index > 0); + --index; +} + } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h index dc870f626f2..77c767c34a0 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/MacroExpander.h @@ -7,13 +7,11 @@ #ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_ #define COMPILER_PREPROCESSOR_MACROEXPANDER_H_ -#include <cassert> #include <memory> #include <vector> -#include "Lexer.h" -#include "Macro.h" -#include "pp_utils.h" +#include "compiler/preprocessor/Lexer.h" +#include "compiler/preprocessor/Macro.h" namespace pp { @@ -24,14 +22,12 @@ struct SourceLocation; class MacroExpander : public Lexer { public: - MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics, bool parseDefined); + MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics); ~MacroExpander() override; void lex(Token *token) override; private: - PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander); - void getToken(Token *token); void ungetToken(const Token &token); bool isNextTokenLeftParen(); @@ -54,37 +50,23 @@ class MacroExpander : public Lexer struct MacroContext { + MacroContext(); + bool empty() const; + const Token &get(); + void unget(); + const Macro *macro; std::size_t index; std::vector<Token> replacements; - - MacroContext() - : macro(0), - index(0) - { - } - bool empty() const - { - return index == replacements.size(); - } - const Token &get() - { - return replacements[index++]; - } - void unget() - { - assert(index > 0); - --index; - } }; Lexer *mLexer; MacroSet *mMacroSet; Diagnostics *mDiagnostics; - bool mParseDefined; std::unique_ptr<Token> mReserveToken; std::vector<MacroContext *> mContextStack; + size_t mTotalTokensInContexts; }; } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp index aeb9c46f9dc..1709d6673d7 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.cpp @@ -4,16 +4,15 @@ // found in the LICENSE file. // -#include "Preprocessor.h" +#include "compiler/preprocessor/Preprocessor.h" -#include <cassert> - -#include "DiagnosticsBase.h" -#include "DirectiveParser.h" -#include "Macro.h" -#include "MacroExpander.h" -#include "Token.h" -#include "Tokenizer.h" +#include "common/debug.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/DirectiveParser.h" +#include "compiler/preprocessor/Macro.h" +#include "compiler/preprocessor/MacroExpander.h" +#include "compiler/preprocessor/Token.h" +#include "compiler/preprocessor/Tokenizer.h" namespace pp { @@ -30,7 +29,7 @@ struct PreprocessorImpl : diagnostics(diag), tokenizer(diag), directiveParser(&tokenizer, ¯oSet, diag, directiveHandler), - macroExpander(&directiveParser, ¯oSet, diag, false) + macroExpander(&directiveParser, ¯oSet, diag) { } }; @@ -78,8 +77,8 @@ void Preprocessor::lex(Token *token) // Convert preprocessing tokens to compiler tokens or report // diagnostics. case Token::PP_HASH: - assert(false); - break; + UNREACHABLE(); + break; case Token::PP_NUMBER: mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER, token->location, token->text); diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h index fe25daa1239..cd699786fce 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Preprocessor.h @@ -7,9 +7,9 @@ #ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_ #define COMPILER_PREPROCESSOR_PREPROCESSOR_H_ -#include <stddef.h> +#include <cstddef> -#include "pp_utils.h" +#include "common/angleutils.h" namespace pp { @@ -19,7 +19,7 @@ class DirectiveHandler; struct PreprocessorImpl; struct Token; -class Preprocessor +class Preprocessor : angle::NonCopyable { public: Preprocessor(Diagnostics *diagnostics, DirectiveHandler *directiveHandler); @@ -44,8 +44,6 @@ class Preprocessor void setMaxTokenSize(size_t maxTokenSize); private: - PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor); - PreprocessorImpl *mImpl; }; diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp index d102654747d..41610a4023f 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Token.cpp @@ -4,11 +4,10 @@ // found in the LICENSE file. // -#include "Token.h" +#include "compiler/preprocessor/Token.h" -#include <cassert> - -#include "numeric_lex.h" +#include "common/debug.h" +#include "compiler/preprocessor/numeric_lex.h" namespace pp { @@ -55,19 +54,19 @@ void Token::setExpansionDisabled(bool disable) bool Token::iValue(int *value) const { - assert(type == CONST_INT); + ASSERT(type == CONST_INT); return numeric_lex_int(text, value); } bool Token::uValue(unsigned int *value) const { - assert(type == CONST_INT); + ASSERT(type == CONST_INT); return numeric_lex_int(text, value); } bool Token::fValue(float *value) const { - assert(type == CONST_FLOAT); + ASSERT(type == CONST_FLOAT); return numeric_lex_float(text, value); } diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Token.h b/chromium/third_party/angle/src/compiler/preprocessor/Token.h index 347c47e3072..716503b3297 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Token.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Token.h @@ -10,7 +10,7 @@ #include <ostream> #include <string> -#include "SourceLocation.h" +#include "compiler/preprocessor/SourceLocation.h" namespace pp { @@ -113,7 +113,7 @@ inline bool operator!=(const Token &lhs, const Token &rhs) return !lhs.equals(rhs); } -extern std::ostream &operator<<(std::ostream &out, const Token &token); +std::ostream &operator<<(std::ostream &out, const Token &token); } // namepsace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp index eb6156f4751..40e910e2214 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp +++ b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.cpp @@ -9,20 +9,96 @@ -#line 13 "./Tokenizer.cpp" - #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ + + + + + + + + + + #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 39 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 1 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ @@ -56,7 +132,6 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; -typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -98,30 +173,27 @@ typedef unsigned int flex_uint32_t; #endif /* ! FLEXINT_H */ -#ifdef __cplusplus -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST -#else /* ! __cplusplus */ +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) -#define YY_USE_CONST + -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif /* Returned upon end-of-file. */ #define YY_NULL 0 + + /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the @@ -129,12 +201,34 @@ typedef unsigned int flex_uint32_t; */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + + + + /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif + + + + + + + + + + + + + + + + + + /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r @@ -146,12 +240,29 @@ typedef void* yyscan_t; #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r + + + + + + + + + + + + + + + /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * + + /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. @@ -159,23 +270,41 @@ typedef void* yyscan_t; #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START + + /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + + /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE pprestart(yyin ,yyscanner ) + + #define YY_END_OF_BUFFER_CHAR 0 + /* Size of default input buffer. */ #ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else #define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ #endif + /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + + #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; @@ -186,18 +315,22 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; typedef size_t yy_size_t; #endif -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif + + #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 + + + #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) + + + /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ @@ -212,26 +345,31 @@ typedef size_t yy_size_t; } \ while ( 0 ) + + #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ - yy_size_t yy_buf_size; + int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - yy_size_t yy_n_chars; + int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -255,6 +393,7 @@ struct yy_buffer_state int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ + /* Whether to try to fill the input buffer when we reach the * end of it. */ @@ -279,6 +418,10 @@ struct yy_buffer_state }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ + + + + /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". @@ -289,11 +432,18 @@ struct yy_buffer_state ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) + + /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + + + + + void pprestart (FILE *input_file ,yyscan_t yyscanner ); void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); @@ -302,22 +452,30 @@ void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); void pppop_buffer_state (yyscan_t yyscanner ); + static void ppensure_buffer_stack (yyscan_t yyscanner ); static void pp_load_buffer_state (yyscan_t yyscanner ); static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + + #define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + void *ppalloc (yy_size_t ,yyscan_t yyscanner ); void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner ); void ppfree (void * ,yyscan_t yyscanner ); + #define yy_new_buffer pp_create_buffer + + #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ @@ -328,6 +486,8 @@ void ppfree (void * ,yyscan_t yyscanner ); YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } + + #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ @@ -338,34 +498,50 @@ void ppfree (void * ,yyscan_t yyscanner ); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } + + #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + /* Begin user sect3 */ -#define ppwrap(yyscanner) 1 +#define ppwrap(yyscanner) (/*CONSTCOND*/1) #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; + + + typedef int yy_state_type; #define yytext_ptr yytext_r + + + + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); +static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner ); + + + /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ - yyleng = (yy_size_t) (yy_cp - yy_bp); \ + yyleng = (int) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; + + #define YY_NUM_RULES 38 #define YY_END_OF_BUFFER 39 /* This struct is not used in this scanner, @@ -390,7 +566,7 @@ static yyconst flex_int16_t yy_accept[98] = } ; -static yyconst flex_int32_t yy_ec[256] = +static yyconst YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, @@ -422,14 +598,14 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[30] = +static yyconst YY_CHAR yy_meta[30] = { 0, 1, 1, 2, 2, 1, 1, 1, 1, 1, 3, 1, 1, 4, 1, 5, 5, 5, 1, 1, 1, 5, 5, 5, 5, 5, 5, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[103] = +static yyconst flex_uint16_t yy_base[103] = { 0, 0, 0, 27, 29, 137, 194, 133, 194, 117, 100, 194, 98, 26, 194, 94, 24, 28, 33, 32, 39, @@ -461,7 +637,7 @@ static yyconst flex_int16_t yy_def[103] = 97, 97 } ; -static yyconst flex_int16_t yy_nxt[224] = +static yyconst flex_uint16_t yy_nxt[224] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, @@ -544,10 +720,10 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. #pragma warning(disable: 4005) #endif -#include "Tokenizer.h" +#include "compiler/preprocessor/Tokenizer.h" -#include "DiagnosticsBase.h" -#include "Token.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/Token.h" #if defined(__GNUC__) // Triggered by the auto-generated yy_fatal_error function. @@ -596,11 +772,23 @@ typedef pp::SourceLocation YYLTYPE; #define YY_INPUT(buf, result, maxSize) \ result = yyextra->input.read(buf, maxSize, &yylineno); + + + + #define INITIAL 0 #define COMMENT 1 + + + + + #define YY_EXTRA_TYPE pp::Tokenizer::Context* + + + /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { @@ -614,8 +802,8 @@ struct yyguts_t size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; - yy_size_t yy_n_chars; - yy_size_t yyleng_r; + int yy_n_chars; + int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; @@ -629,69 +817,132 @@ struct yyguts_t int yylineno_r; int yy_flex_debug_r; + + + char *yytext_r; int yy_more_flag; int yy_more_len; + + YYSTYPE * yylval_r; + + YYLTYPE * yylloc_r; + }; /* end struct yyguts_t */ + + + static int yy_init_globals (yyscan_t yyscanner ); + + + + /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r + + # define yylloc yyg->yylloc_r + + int pplex_init (yyscan_t* scanner); int pplex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + + /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ + int pplex_destroy (yyscan_t yyscanner ); + + int ppget_debug (yyscan_t yyscanner ); + + void ppset_debug (int debug_flag ,yyscan_t yyscanner ); + + YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner ); + + void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + + FILE *ppget_in (yyscan_t yyscanner ); -void ppset_in (FILE * in_str ,yyscan_t yyscanner ); + + +void ppset_in (FILE * _in_str ,yyscan_t yyscanner ); + + FILE *ppget_out (yyscan_t yyscanner ); -void ppset_out (FILE * out_str ,yyscan_t yyscanner ); -yy_size_t ppget_leng (yyscan_t yyscanner ); + +void ppset_out (FILE * _out_str ,yyscan_t yyscanner ); + + + + int ppget_leng (yyscan_t yyscanner ); + + char *ppget_text (yyscan_t yyscanner ); + + int ppget_lineno (yyscan_t yyscanner ); -void ppset_lineno (int line_number ,yyscan_t yyscanner ); + + +void ppset_lineno (int _line_number ,yyscan_t yyscanner ); + + + int ppget_column (yyscan_t yyscanner ); -void ppset_column (int column_no ,yyscan_t yyscanner ); + + + + +void ppset_column (int _column_no ,yyscan_t yyscanner ); + + + YYSTYPE * ppget_lval (yyscan_t yyscanner ); + void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + + YYLTYPE *ppget_lloc (yyscan_t yyscanner ); + + void ppset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + + /* Macros after this point can all be overridden by user definitions in * section 1. */ @@ -704,6 +955,12 @@ extern int ppwrap (yyscan_t yyscanner ); #endif #endif + +#ifndef YY_NO_UNPUT + +#endif + + #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); #endif @@ -722,19 +979,34 @@ static int input (yyscan_t yyscanner ); #endif + + + + + + + /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else #define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ #endif + /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif + + /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ @@ -756,7 +1028,7 @@ static int input (yyscan_t yyscanner ); else \ { \ errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ @@ -771,6 +1043,8 @@ static int input (yyscan_t yyscanner ); #endif + + /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. @@ -779,24 +1053,48 @@ static int input (yyscan_t yyscanner ); #define yyterminate() return YY_NULL #endif + /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif + /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif + + + + /* end tables serialization structures and prototypes */ + + /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 + + + + + + + + + + + + + + + + extern int pplex \ (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); @@ -804,6 +1102,7 @@ extern int pplex \ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) #endif /* !YY_DECL */ + /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ @@ -811,27 +1110,39 @@ extern int pplex \ #define YY_USER_ACTION #endif + + /* Code executed at the end of each rule. */ #ifndef YY_BREAK -#define YY_BREAK break; +#define YY_BREAK /*LINTED*/break; #endif + + #define YY_RULE_SETUP \ YY_USER_ACTION + + /** The main scanner function which does all the work. */ YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + + yylval = yylval_param; + + yylloc = yylloc_param; + if ( !yyg->yy_init ) { yyg->yy_init = 1; @@ -840,6 +1151,8 @@ YY_DECL YY_USER_INIT; #endif + + if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ @@ -860,9 +1173,10 @@ YY_DECL { + /* Line comment */ - while ( 1 ) /* loops until end-of-file is reached */ + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; @@ -878,7 +1192,7 @@ YY_DECL yy_match: do { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; @@ -890,7 +1204,7 @@ yy_match: if ( yy_current_state >= 98 ) yy_c = yy_meta[(unsigned int) yy_c]; } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++yy_cp; } while ( yy_current_state != 97 ); @@ -902,8 +1216,11 @@ yy_find_action: YY_DO_BEFORE_ACTION; + + do_action: /* This label is used only to access EOF actions. */ + switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ @@ -1326,6 +1643,11 @@ ECHO; } /* end of user's declarations */ } /* end of pplex */ + + + + + /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: @@ -1336,9 +1658,9 @@ ECHO; static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = yyg->yytext_ptr; + yy_size_t number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) @@ -1367,7 +1689,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); @@ -1380,8 +1702,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { - yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + int num_to_read = + static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1); while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ @@ -1394,7 +1716,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( b->yy_is_our_buffer ) { - yy_size_t new_size = b->yy_buf_size * 2; + int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1407,7 +1729,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) } else /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; + b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( @@ -1415,8 +1737,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; + num_to_read = static_cast<int>(YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1); } @@ -1424,8 +1746,10 @@ static int yy_get_next_buffer (yyscan_t yyscanner) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ + yy_size_t ret = 0; YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, num_to_read ); + ret, num_to_read ); + yyg->yy_n_chars = static_cast<int>(ret); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } @@ -1449,7 +1773,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else ret_val = EOB_ACT_CONTINUE_SCAN; - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); @@ -1457,7 +1781,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } - yyg->yy_n_chars += number_to_move; + yyg->yy_n_chars += static_cast<int>(number_to_move); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; @@ -1466,19 +1790,21 @@ static int yy_get_next_buffer (yyscan_t yyscanner) return ret_val; } + /* yy_get_previous_state - get the state just before the EOB char was reached */ + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { - register yy_state_type yy_current_state; - register char *yy_cp; + yy_state_type yy_current_state; + char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; @@ -1490,12 +1816,13 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( yy_current_state >= 98 ) yy_c = yy_meta[(unsigned int) yy_c]; } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; } return yy_current_state; } + /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis @@ -1503,11 +1830,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { - register int yy_is_jam; + int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; + char *yy_cp = yyg->yy_c_buf_p; - register YY_CHAR yy_c = 1; + YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; @@ -1519,13 +1846,18 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( yy_current_state >= 98 ) yy_c = yy_meta[(unsigned int) yy_c]; } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; yy_is_jam = (yy_current_state == 97); (void)yyg; return yy_is_jam ? 0 : yy_current_state; } + +#ifndef YY_NO_UNPUT + +#endif + #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) @@ -1551,7 +1883,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { /* need more input */ - yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) @@ -1575,7 +1907,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) case EOB_ACT_END_OF_FILE: { if ( ppwrap(yyscanner ) ) - return EOF; + return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; @@ -1597,6 +1929,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; + return c; } #endif /* ifndef YY_NO_INPUT */ @@ -1620,6 +1953,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) pp_load_buffer_state(yyscanner ); } + /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. @@ -1656,6 +1990,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yyg->yy_did_buffer_switch_on_eof = 1; } + static void pp_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; @@ -1679,7 +2014,7 @@ static void pp_load_buffer_state (yyscan_t yyscanner) if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); - b->yy_buf_size = size; + b->yy_buf_size = (yy_size_t)size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. @@ -1695,6 +2030,7 @@ static void pp_load_buffer_state (yyscan_t yyscanner) return b; } + /** Destroy the buffer. * @param b a buffer created with pp_create_buffer() * @param yyscanner The scanner object. @@ -1715,6 +2051,7 @@ static void pp_load_buffer_state (yyscan_t yyscanner) ppfree((void *) b ,yyscanner ); } + /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a pprestart() or at EOF. @@ -1739,8 +2076,11 @@ static void pp_load_buffer_state (yyscan_t yyscanner) b->yy_bs_column = 0; } + + b->yy_is_interactive = 0; + errno = oerrno; } @@ -1805,6 +2145,7 @@ void pppush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) yyg->yy_did_buffer_switch_on_eof = 1; } + /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. @@ -1826,6 +2167,7 @@ void pppop_buffer_state (yyscan_t yyscanner) } } + /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ @@ -1840,13 +2182,14 @@ static void ppensure_buffer_stack (yyscan_t yyscanner) * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ - num_to_alloc = 1; + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ yyg->yy_buffer_stack = (struct yy_buffer_state**)ppalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; @@ -1857,7 +2200,7 @@ static void ppensure_buffer_stack (yyscan_t yyscanner) if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; + yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)pprealloc @@ -1873,6 +2216,10 @@ static void ppensure_buffer_stack (yyscan_t yyscanner) } } + + + + /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer @@ -1887,16 +2234,16 @@ YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ - return 0; + return NULL; b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" ); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_size = static_cast<int>(size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; - b->yy_input_file = 0; + b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; @@ -1908,6 +2255,9 @@ YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann return b; } + + + /** Setup the input buffer state to scan a string. The next call to pplex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan @@ -1919,9 +2269,12 @@ YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscann YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) { - return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner); + return pp_scan_bytes(yystr,(int) strlen(yystr) ,yyscanner); } + + + /** Setup the input buffer state to scan the given bytes. The next call to pplex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan @@ -1929,7 +2282,7 @@ YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) +YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; @@ -1937,12 +2290,12 @@ YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; + n = (yy_size_t) _yybytes_len + 2; buf = (char *) ppalloc(n ,yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" ); - for ( i = 0; i < _yybytes_len; ++i ) + for ( i = 0; i < static_cast<yy_size_t>(_yybytes_len); ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; @@ -1959,13 +2312,25 @@ YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len return b; } + + + + + + + + + + #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) { - (void) fprintf( stderr, "%s\n", msg ); + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } @@ -1986,8 +2351,11 @@ static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) } \ while ( 0 ) + + /* Accessor methods (get/set functions) to struct members. */ + /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ @@ -1997,6 +2365,8 @@ YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner) return yyextra; } + + /** Get the current line number. * @param yyscanner The scanner object. */ @@ -2004,12 +2374,16 @@ int ppget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (! YY_CURRENT_BUFFER) return 0; return yylineno; } + + + /** Get the current column number. * @param yyscanner The scanner object. */ @@ -2017,12 +2391,16 @@ int ppget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } + + + /** Get the input stream. * @param yyscanner The scanner object. */ @@ -2032,6 +2410,8 @@ FILE *ppget_in (yyscan_t yyscanner) return yyin; } + + /** Get the output stream. * @param yyscanner The scanner object. */ @@ -2041,15 +2421,18 @@ FILE *ppget_out (yyscan_t yyscanner) return yyout; } + + /** Get the length of the current token. * @param yyscanner The scanner object. */ -yy_size_t ppget_leng (yyscan_t yyscanner) +int ppget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } + /** Get the current token. * @param yyscanner The scanner object. */ @@ -2060,6 +2443,8 @@ char *ppget_text (yyscan_t yyscanner) return yytext; } + + /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. @@ -2070,92 +2455,123 @@ void ppset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) yyextra = user_defined ; } + + /** Set the current line number. - * @param line_number + * @param _line_number line number * @param yyscanner The scanner object. */ -void ppset_lineno (int line_number , yyscan_t yyscanner) +void ppset_lineno (int _line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "ppset_lineno called with no buffer" ); - yylineno = line_number; + yylineno = _line_number; } + + + /** Set the current column. - * @param line_number + * @param _column_no column number * @param yyscanner The scanner object. */ -void ppset_column (int column_no , yyscan_t yyscanner) +void ppset_column (int _column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) YY_FATAL_ERROR( "ppset_column called with no buffer" ); - yycolumn = column_no; + yycolumn = _column_no; } + + + + /** Set the input stream. This does not discard the current * input buffer. - * @param in_str A readable stream. + * @param _in_str A readable stream. * @param yyscanner The scanner object. * @see pp_switch_to_buffer */ -void ppset_in (FILE * in_str , yyscan_t yyscanner) +void ppset_in (FILE * _in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; + yyin = _in_str ; } -void ppset_out (FILE * out_str , yyscan_t yyscanner) + + +void ppset_out (FILE * _out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; + yyout = _out_str ; } + + + int ppget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } -void ppset_debug (int bdebug , yyscan_t yyscanner) + + +void ppset_debug (int _bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; + yy_flex_debug = _bdebug ; } + /* Accessor methods for yylval and yylloc */ + YYSTYPE * ppget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } + + void ppset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } + + + YYLTYPE *ppget_lloc (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylloc; } + + void ppset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylloc = yylloc_param; } + + + + /* User-visible API */ /* pplex_init is special because it creates the scanner itself, so it is @@ -2184,6 +2600,7 @@ int pplex_init(yyscan_t* ptr_yy_globals) return yy_init_globals ( *ptr_yy_globals ); } + /* pplex_init_extra has the same functionality as pplex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and @@ -2220,6 +2637,7 @@ int pplex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) return yy_init_globals ( *ptr_yy_globals ); } + static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; @@ -2227,24 +2645,31 @@ static int yy_init_globals (yyscan_t yyscanner) * This function is called from pplex_destroy(), so don't allocate here. */ - yyg->yy_buffer_stack = 0; + + yyg->yy_buffer_stack = NULL; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; + yyg->yy_c_buf_p = NULL; yyg->yy_init = 0; yyg->yy_start = 0; + yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; + + + + + /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else - yyin = (FILE *) 0; - yyout = (FILE *) 0; + yyin = NULL; + yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by @@ -2253,6 +2678,7 @@ static int yy_init_globals (yyscan_t yyscanner) return 0; } + /* pplex_destroy is for both reentrant and non-reentrant scanners. */ int pplex_destroy (yyscan_t yyscanner) { @@ -2269,10 +2695,14 @@ int pplex_destroy (yyscan_t yyscanner) ppfree(yyg->yy_buffer_stack ,yyscanner); yyg->yy_buffer_stack = NULL; + /* Destroy the start condition stack. */ ppfree(yyg->yy_start_stack ,yyscanner ); yyg->yy_start_stack = NULL; + + + /* Reset the globals. This is important in a non-reentrant scanner so the next time * pplex() is called, initialization will occur. */ yy_init_globals( yyscanner); @@ -2283,23 +2713,32 @@ int pplex_destroy (yyscan_t yyscanner) return 0; } + + /* * Internal utility routines. */ + + #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) { - register int i; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + + int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif + + #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) { - register int n; + int n; for ( n = 0; s[n]; ++n ) ; @@ -2307,13 +2746,22 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) } #endif + + void *ppalloc (yy_size_t size , yyscan_t yyscanner) { - return (void *) malloc( size ); + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + return malloc(size); } + + void *pprealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; + /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter @@ -2321,21 +2769,32 @@ void *pprealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ - return (void *) realloc( (char *) ptr, size ); + return realloc(ptr, size); } + + void ppfree (void * ptr , yyscan_t yyscanner) { + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + (void)yyg; free( (char *) ptr ); /* see pprealloc() for (char *) cast */ } + #define YYTABLES_NAME "yytables" + + + + + + + + namespace pp { -Tokenizer::Tokenizer(Diagnostics *diagnostics) - : mHandle(0), - mMaxTokenSize(256) +Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256) { mContext.diagnostics = diagnostics; } @@ -2392,7 +2851,7 @@ void Tokenizer::lex(Token *token) bool Tokenizer::initScanner() { - if ((mHandle == NULL) && pplex_init_extra(&mContext,&mHandle)) + if ((mHandle == nullptr) && pplex_init_extra(&mContext, &mHandle)) return false; pprestart(0,mHandle); @@ -2401,12 +2860,13 @@ bool Tokenizer::initScanner() void Tokenizer::destroyScanner() { - if (mHandle == NULL) + if (mHandle == nullptr) return; pplex_destroy(mHandle); - mHandle = NULL; + mHandle = nullptr; } } // namespace pp + diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h index 49e64fa209f..6dfb19c6692 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h +++ b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.h @@ -7,9 +7,9 @@ #ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_ #define COMPILER_PREPROCESSOR_TOKENIZER_H_ -#include "Input.h" -#include "Lexer.h" -#include "pp_utils.h" +#include "common/angleutils.h" +#include "compiler/preprocessor/Input.h" +#include "compiler/preprocessor/Lexer.h" namespace pp { @@ -45,7 +45,6 @@ class Tokenizer : public Lexer void lex(Token *token) override; private: - PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer); bool initScanner(); void destroyScanner(); diff --git a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l index d316da88b1d..62eb4caa65f 100644 --- a/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l +++ b/chromium/third_party/angle/src/compiler/preprocessor/Tokenizer.l @@ -27,10 +27,10 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. #pragma warning(disable: 4005) #endif -#include "Tokenizer.h" +#include "compiler/preprocessor/Tokenizer.h" -#include "DiagnosticsBase.h" -#include "Token.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/Token.h" #if defined(__GNUC__) // Triggered by the auto-generated yy_fatal_error function. @@ -280,9 +280,7 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") namespace pp { -Tokenizer::Tokenizer(Diagnostics *diagnostics) - : mHandle(0), - mMaxTokenSize(256) +Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256) { mContext.diagnostics = diagnostics; } @@ -339,7 +337,7 @@ void Tokenizer::lex(Token *token) bool Tokenizer::initScanner() { - if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle)) + if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle)) return false; yyrestart(0, mHandle); @@ -348,11 +346,11 @@ bool Tokenizer::initScanner() void Tokenizer::destroyScanner() { - if (mHandle == NULL) + if (mHandle == nullptr) return; yylex_destroy(mHandle); - mHandle = NULL; + mHandle = nullptr; } } // namespace pp diff --git a/chromium/third_party/angle/src/compiler/preprocessor/pp_utils.h b/chromium/third_party/angle/src/compiler/preprocessor/pp_utils.h deleted file mode 100644 index 9fba9385c5e..00000000000 --- a/chromium/third_party/angle/src/compiler/preprocessor/pp_utils.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// pp_utils.h: Common preprocessor utilities - -#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_ -#define COMPILER_PREPROCESSOR_PPUTILS_H_ - -// A macro to disallow the copy constructor and operator= functions -// This must be used in the private: declarations for a class. -#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName &); \ - void operator=(const TypeName &) - -#endif // COMPILER_PREPROCESSOR_PPUTILS_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.cpp index 31bfae9966f..1fa3c59a690 100644 --- a/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.cpp @@ -72,9 +72,9 @@ class PullGradient : public TIntermTraverser return true; } - bool visitSelection(Visit visit, TIntermSelection *selection) override + bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override { - visitControlFlow(visit, selection); + visitControlFlow(visit, ifElse); return true; } @@ -196,7 +196,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser return true; } - bool visitSelection(Visit visit, TIntermSelection *node) override + bool visitIfElse(Visit visit, TIntermIfElse *node) override { if (visit == PreVisit) { @@ -310,7 +310,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser const CallDAG &mDag; std::vector<TIntermNode*> mLoopsAndSwitches; - std::vector<TIntermSelection*> mIfs; + std::vector<TIntermIfElse *> mIfs; }; // Tags all the functions called in a discontinuous loop @@ -385,7 +385,7 @@ bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node) return mControlFlowsContainingGradient.count(node) > 0; } -bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node) +bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node) { return mIfsContainingGradientLoop.count(node) > 0; } diff --git a/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.h b/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.h index 39e671e3e02..4795bc38779 100644 --- a/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/ASTMetadataHLSL.h @@ -14,7 +14,7 @@ class CallDAG; class TIntermNode; -class TIntermSelection; +class TIntermIfElse; class TIntermLoop; struct ASTMetadataHLSL @@ -30,7 +30,7 @@ struct ASTMetadataHLSL // Here "something uses a gradient" means here that it either contains a // gradient operation, or a call to a function that uses a gradient. bool hasGradientInCallGraph(TIntermLoop *node); - bool hasGradientLoop(TIntermSelection *node); + bool hasGradientLoop(TIntermIfElse *node); // Does the function use a gradient. bool mUsesGradient; @@ -44,7 +44,7 @@ struct ASTMetadataHLSL bool mCalledInDiscontinuousLoop; bool mHasGradientLoopInCallGraph; std::set<TIntermLoop*> mDiscontinuousLoops; - std::set<TIntermSelection *> mIfsContainingGradientLoop; + std::set<TIntermIfElse *> mIfsContainingGradientLoop; // Will we need to generate a Lod0 version of the function. bool mNeedsLod0; diff --git a/chromium/third_party/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp b/chromium/third_party/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp new file mode 100644 index 00000000000..0177fea968a --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp @@ -0,0 +1,59 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/AddAndTrueToLoopCondition.h" + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +namespace +{ + +// An AST traverser that rewrites for and while loops by replacing "condition" with +// "condition && true" to work around condition bug on Intel Mac. +class AddAndTrueToLoopConditionTraverser : public TIntermTraverser +{ + public: + AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {} + + bool visitLoop(Visit, TIntermLoop *loop) override + { + // do-while loop doesn't have this bug. + if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile) + { + return true; + } + + // For loop may not have a condition. + if (loop->getCondition() == nullptr) + { + return true; + } + + // Constant true. + TConstantUnion *trueConstant = new TConstantUnion(); + trueConstant->setBConst(true); + TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, TType(EbtBool)); + + // CONDITION && true. + TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue); + loop->setCondition(andOp); + + return true; + } +}; + +} // anonymous namespace + +void AddAndTrueToLoopCondition(TIntermNode *root) +{ + AddAndTrueToLoopConditionTraverser traverser; + root->traverse(&traverser); +} + +} // namespace sh diff --git a/chromium/third_party/angle/src/compiler/translator/AddAndTrueToLoopCondition.h b/chromium/third_party/angle/src/compiler/translator/AddAndTrueToLoopCondition.h new file mode 100644 index 00000000000..34debe0ed97 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/AddAndTrueToLoopCondition.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Rewrite condition in for and while loops to work around driver bug on Intel Mac. + +#ifndef COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_ +#define COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_ + +class TIntermNode; +namespace sh +{ + +void AddAndTrueToLoopCondition(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/AddDefaultReturnStatements.cpp b/chromium/third_party/angle/src/compiler/translator/AddDefaultReturnStatements.cpp new file mode 100644 index 00000000000..25493a50bec --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/AddDefaultReturnStatements.cpp @@ -0,0 +1,77 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// AddDefaultReturnStatements.cpp: Add default return statements to functions that do not end in a +// return. +// + +#include "compiler/translator/AddDefaultReturnStatements.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +class AddDefaultReturnStatementsTraverser : private TIntermTraverser +{ + public: + static void Apply(TIntermNode *root) + { + AddDefaultReturnStatementsTraverser separateInit; + root->traverse(&separateInit); + separateInit.updateTree(); + } + + private: + AddDefaultReturnStatementsTraverser() : TIntermTraverser(true, false, false) {} + + static bool IsFunctionWithoutReturnStatement(TIntermAggregate *node, TType *returnType) + { + *returnType = node->getType(); + if (node->getOp() != EOpFunction || node->getType().getBasicType() == EbtVoid) + { + return false; + } + + TIntermAggregate *bodyNode = node->getSequence()->back()->getAsAggregate(); + ASSERT(bodyNode); + TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode(); + if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn) + { + return false; + } + + return true; + } + + bool visitAggregate(Visit, TIntermAggregate *node) override + { + TType returnType; + if (IsFunctionWithoutReturnStatement(node, &returnType)) + { + TIntermBranch *branch = + new TIntermBranch(EOpReturn, TIntermTyped::CreateZero(returnType)); + + TIntermAggregate *bodyNode = node->getSequence()->back()->getAsAggregate(); + bodyNode->getSequence()->push_back(branch); + + return false; + } + + return true; + } +}; +} // anonymous namespace + +void AddDefaultReturnStatements(TIntermNode *node) +{ + AddDefaultReturnStatementsTraverser::Apply(node); +} + +} // namespace sh diff --git a/chromium/third_party/angle/src/compiler/translator/AddDefaultReturnStatements.h b/chromium/third_party/angle/src/compiler/translator/AddDefaultReturnStatements.h new file mode 100644 index 00000000000..d765a7ae4ab --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/AddDefaultReturnStatements.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// AddDefaultReturnStatements.h: Add default return statements to functions that do not end in a +// return. +// + +#ifndef COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_ +#define COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_ + +class TIntermNode; + +namespace sh +{ + +void AddDefaultReturnStatements(TIntermNode *node); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/chromium/third_party/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp index 510ade84c1f..562d53d7b04 100644 --- a/chromium/third_party/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp @@ -103,7 +103,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType())); replacementParams->setLine(params->getLine()); - mReplacements.push_back(NodeUpdateEntry(node, params, replacementParams, false)); + queueReplacementWithParent(node, params, replacementParams, + OriginalNode::IS_DROPPED); node->setType(TType(EbtVoid)); @@ -122,7 +123,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TInter replacement->setLine(node->getLine()); replacement->setType(TType(EbtVoid)); - mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, replacement, false)); + queueReplacement(node, replacement, OriginalNode::IS_DROPPED); } else if (node->getOp() == EOpFunctionCall) { @@ -166,12 +167,11 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr // Instead of returning a value, assign to the out parameter and then return. TIntermSequence replacements; - TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign); TIntermTyped *expression = node->getExpression(); ASSERT(expression != nullptr); - replacementAssignment->setLeft(CreateReturnValueSymbol(expression->getType())); - replacementAssignment->setRight(node->getExpression()); - replacementAssignment->setType(expression->getType()); + TIntermSymbol *returnValueSymbol = CreateReturnValueSymbol(expression->getType()); + TIntermBinary *replacementAssignment = + new TIntermBinary(EOpAssign, returnValueSymbol, expression); replacementAssignment->setLine(expression->getLine()); replacements.push_back(replacementAssignment); @@ -192,7 +192,7 @@ bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBi if (rightAgg != nullptr && rightAgg->getOp() == EOpFunctionCall && rightAgg->isUserDefined()) { TIntermAggregate *replacementCall = CreateReplacementCall(rightAgg, node->getLeft()); - mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, replacementCall, false)); + queueReplacement(node, replacementCall, OriginalNode::IS_DROPPED); } } return false; diff --git a/chromium/third_party/angle/src/compiler/translator/BaseTypes.h b/chromium/third_party/angle/src/compiler/translator/BaseTypes.h index 69dd60f0d69..0919955f574 100644 --- a/chromium/third_party/angle/src/compiler/translator/BaseTypes.h +++ b/chromium/third_party/angle/src/compiler/translator/BaseTypes.h @@ -7,7 +7,11 @@ #ifndef COMPILER_TRANSLATOR_BASETYPES_H_ #define COMPILER_TRANSLATOR_BASETYPES_H_ +#include <algorithm> +#include <array> + #include "common/debug.h" +#include "GLSLANG/ShaderLang.h" // // Precision qualifiers @@ -337,19 +341,34 @@ enum TQualifier EvqLastFragData, // GLSL ES 3.0 vertex output and fragment input - EvqSmooth, // Incomplete qualifier, smooth is the default - EvqFlat, // Incomplete qualifier - EvqSmoothOut = EvqSmooth, - EvqFlatOut = EvqFlat, + EvqSmooth, // Incomplete qualifier, smooth is the default + EvqFlat, // Incomplete qualifier + EvqCentroid, // Incomplete qualifier + EvqSmoothOut, + EvqFlatOut, EvqCentroidOut, // Implies smooth EvqSmoothIn, EvqFlatIn, EvqCentroidIn, // Implies smooth + // GLSL ES 3.1 compute shader special variables + EvqComputeIn, + EvqNumWorkGroups, + EvqWorkGroupSize, + EvqWorkGroupID, + EvqLocalInvocationID, + EvqGlobalInvocationID, + EvqLocalInvocationIndex, + // end of list EvqLast }; +inline bool IsQualifierUnspecified(TQualifier qualifier) +{ + return (qualifier == EvqTemporary || qualifier == EvqGlobal); +} + enum TLayoutMatrixPacking { EmpUnspecified, @@ -368,26 +387,65 @@ enum TLayoutBlockStorage struct TLayoutQualifier { int location; + unsigned int locationsSpecified; TLayoutMatrixPacking matrixPacking; TLayoutBlockStorage blockStorage; + // Compute shader layout qualifiers. + sh::WorkGroupSize localSize; + static TLayoutQualifier create() { TLayoutQualifier layoutQualifier; layoutQualifier.location = -1; + layoutQualifier.locationsSpecified = 0; layoutQualifier.matrixPacking = EmpUnspecified; layoutQualifier.blockStorage = EbsUnspecified; + layoutQualifier.localSize.fill(-1); + return layoutQualifier; } bool isEmpty() const { - return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified; + return location == -1 && matrixPacking == EmpUnspecified && + blockStorage == EbsUnspecified && !localSize.isAnyValueSet(); + } + + bool isCombinationValid() const + { + bool workSizeSpecified = localSize.isAnyValueSet(); + bool otherLayoutQualifiersSpecified = + (location != -1 || matrixPacking != EmpUnspecified || blockStorage != EbsUnspecified); + + // we can have either the work group size specified, or the other layout qualifiers + return !(workSizeSpecified && otherLayoutQualifiersSpecified); + } + + bool isLocalSizeEqual(const sh::WorkGroupSize &localSizeIn) const + { + return localSize.isWorkGroupSizeMatching(localSizeIn); } }; +inline const char *getWorkGroupSizeString(size_t dimension) +{ + switch (dimension) + { + case 0u: + return "local_size_x"; + case 1u: + return "local_size_y"; + case 2u: + return "local_size_z"; + default: + UNREACHABLE(); + return "dimension out of bounds"; + } +} + // // This is just for debug print out, carried along with the definitions above. // @@ -427,11 +485,21 @@ inline const char* getQualifierString(TQualifier q) case EvqLastFragColor: return "LastFragColor"; case EvqLastFragData: return "LastFragData"; case EvqSmoothOut: return "smooth out"; - case EvqCentroidOut: return "centroid out"; + case EvqCentroidOut: return "smooth centroid out"; case EvqFlatOut: return "flat out"; case EvqSmoothIn: return "smooth in"; case EvqFlatIn: return "flat in"; - case EvqCentroidIn: return "centroid in"; + case EvqCentroidIn: return "smooth centroid in"; + case EvqCentroid: return "centroid"; + case EvqFlat: return "flat"; + case EvqSmooth: return "smooth"; + case EvqComputeIn: return "in"; + case EvqNumWorkGroups: return "NumWorkGroups"; + case EvqWorkGroupSize: return "WorkGroupSize"; + case EvqWorkGroupID: return "WorkGroupID"; + case EvqLocalInvocationID: return "LocalInvocationID"; + case EvqGlobalInvocationID: return "GlobalInvocationID"; + case EvqLocalInvocationIndex: return "LocalInvocationIndex"; default: UNREACHABLE(); return "unknown qualifier"; } // clang-format on @@ -465,10 +533,10 @@ inline const char* getInterpolationString(TQualifier q) switch(q) { case EvqSmoothOut: return "smooth"; break; - case EvqCentroidOut: return "centroid"; break; + case EvqCentroidOut: return "smooth centroid"; break; case EvqFlatOut: return "flat"; break; case EvqSmoothIn: return "smooth"; break; - case EvqCentroidIn: return "centroid"; break; + case EvqCentroidIn: return "smooth centroid"; break; case EvqFlatIn: return "flat"; break; default: UNREACHABLE(); return "unknown interpolation"; } diff --git a/chromium/third_party/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp b/chromium/third_party/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp new file mode 100644 index 00000000000..aada0fac7df --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp @@ -0,0 +1,106 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend +// may record a variable as aliasing another. Sometimes the alias information gets garbled +// so we work around this issue by breaking the aliasing chain in inner loops. + +#include "BreakVariableAliasingInInnerLoops.h" + +#include "compiler/translator/IntermNode.h" + +// A HLSL compiler developer gave us more details on the root cause and the workaround needed: +// The root problem is that if the HLSL compiler is applying aliasing information even on +// incomplete simulations (in this case, a single pass). The bug is triggered by an assignment +// that comes from a series of assignments, possibly with swizzled or ternary operators with +// known conditionals, where the source is before the loop. +// So, a workaround is to add a +0 term to variables the first time they are assigned to in +// an inner loop (if they are declared in an outside scope, otherwise there is no need). +// This will break the aliasing chain. + +// For simplicity here we add a +0 to any assignment that is in at least two nested loops. Because +// the bug only shows up with swizzles, and ternary assignment, whole array or whole structure +// assignment don't need a workaround. + +namespace +{ + +class AliasingBreaker : public TIntermTraverser +{ + public: + AliasingBreaker() : TIntermTraverser(true, false, true) {} + + protected: + bool visitBinary(Visit visit, TIntermBinary *binary) + { + if (visit != PreVisit) + { + return false; + } + + if (mLoopLevel < 2 || !binary->isAssignment()) + { + return true; + } + + TIntermTyped *B = binary->getRight(); + TType type = B->getType(); + + if (!type.isScalar() && !type.isVector() && !type.isMatrix()) + { + return true; + } + + if (type.isArray() || IsSampler(type.getBasicType())) + { + return true; + } + + // We have a scalar / vector / matrix assignment with loop depth 2. + // Transform it from + // A = B + // to + // A = (B + typeof<B>(0)); + + TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, TIntermTyped::CreateZero(type)); + bPlusZero->setLine(B->getLine()); + + binary->replaceChildNode(B, bPlusZero); + + return true; + } + + bool visitLoop(Visit visit, TIntermLoop *loop) + { + if (visit == PreVisit) + { + mLoopLevel++; + } + else + { + ASSERT(mLoopLevel > 0); + mLoopLevel--; + } + + return true; + } + + private: + int mLoopLevel = 0; +}; + +} // anonymous namespace + +namespace sh +{ + +void BreakVariableAliasingInInnerLoops(TIntermNode *root) +{ + AliasingBreaker breaker; + root->traverse(&breaker); +} + +} // namespace sh diff --git a/chromium/third_party/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h b/chromium/third_party/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h new file mode 100644 index 00000000000..b1d906f9198 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend +// may record a variable as aliasing another. Sometimes the alias information gets garbled +// so we work around this issue by breaking the aliasing chain in inner loops. + +#ifndef COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_ +#define COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_ + +class TIntermNode; + +namespace sh +{ + +void BreakVariableAliasingInInnerLoops(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp index 098560d1107..0c8e2d9cfc1 100644 --- a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp @@ -11,37 +11,96 @@ #include "compiler/translator/SymbolTable.h" #include "compiler/translator/VersionGLSL.h" -void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType) +void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + sh::GLenum shaderType) { - // we use macros here instead of function definitions to work around more GLSL - // compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are - // problematic because if the argument has side-effects they will be repeatedly - // evaluated. This is unlikely to show up in real shaders, but is something to - // consider. + if (shaderType == GL_VERTEX_SHADER) + { + const TType *int1 = TCache::getType(EbtInt); + emu->addEmulatedFunction(EOpAbs, int1, "int webgl_abs_emu(int x) { return x * sign(x); }"); + } +} + +void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion) +{ + // isnan() is supported since GLSL 1.3. + if (targetGLSLVersion < GLSL_VERSION_130) + return; const TType *float1 = TCache::getType(EbtFloat); const TType *float2 = TCache::getType(EbtFloat, 2); const TType *float3 = TCache::getType(EbtFloat, 3); const TType *float4 = TCache::getType(EbtFloat, 4); - if (shaderType == GL_FRAGMENT_SHADER) - { - emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }"); - emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }"); - emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }"); - emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }"); - } - emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))"); - emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))"); - emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))"); - emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))"); - emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))"); + // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false. + emu->addEmulatedFunction( + EOpIsNan, float1, + "bool webgl_isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }"); + emu->addEmulatedFunction( + EOpIsNan, float2, + "bvec2 webgl_isnan_emu(vec2 x)\n" + "{\n" + " bvec2 isnan;\n" + " for (int i = 0; i < 2; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); + emu->addEmulatedFunction( + EOpIsNan, float3, + "bvec3 webgl_isnan_emu(vec3 x)\n" + "{\n" + " bvec3 isnan;\n" + " for (int i = 0; i < 3; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); + emu->addEmulatedFunction( + EOpIsNan, float4, + "bvec4 webgl_isnan_emu(vec4 x)\n" + "{\n" + " bvec4 isnan;\n" + " for (int i = 0; i < 4; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); } // Emulate built-in functions missing from GLSL 1.30 and higher void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType, int targetGLSLVersion) { + // Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10) + if (targetGLSLVersion < GLSL_VERSION_410) + { + const TType *float2 = TCache::getType(EbtFloat, 2); + const TType *uint1 = TCache::getType(EbtUInt); + + // clang-format off + emu->addEmulatedFunction(EOpPackUnorm2x16, float2, + "uint webgl_packUnorm2x16_emu(vec2 v)\n" + "{\n" + " int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n" + " int y = int(round(clamp(v.y, 0.0, 1.0) * 65535.0));\n" + " return uint((y << 16) | (x & 0xFFFF));\n" + "}\n"); + + emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1, + "vec2 webgl_unpackUnorm2x16_emu(uint u)\n" + "{\n" + " float x = float(u & 0xFFFFu) / 65535.0;\n" + " float y = float(u >> 16) / 65535.0;\n" + " return vec2(x, y);\n" + "}\n"); + // clang-format on + } + // Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20) // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30). if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420) @@ -155,7 +214,9 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator " float scale;\n" " if(exponent < 0)\n" " {\n" - " scale = 1.0 / (1 << -exponent);\n" + " // The negative unary operator is buggy on OSX.\n" + " // Work around this by using abs instead.\n" + " scale = 1.0 / (1 << abs(exponent));\n" " }\n" " else\n" " {\n" diff --git a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h index 56242598af5..2bc5f2c8801 100644 --- a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h @@ -12,9 +12,16 @@ class BuiltInFunctionEmulator; // -// This is only a workaround for OpenGL driver bugs, and isn't needed in general. +// This works around bug in Intel Mac drivers. // -void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType); +void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + sh::GLenum shaderType); + +// +// This works around isnan() bug in Intel Mac drivers +// +void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion); // // This function is emulating built-in functions missing from GLSL 1.30 and higher. diff --git a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp index 50e15cbc282..988f1e2bf5e 100644 --- a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp @@ -8,6 +8,59 @@ #include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulatorHLSL.h" #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/VersionGLSL.h" + +void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion) +{ + if (targetGLSLVersion < GLSL_VERSION_130) + return; + + TType *float1 = new TType(EbtFloat); + TType *float2 = new TType(EbtFloat, 2); + TType *float3 = new TType(EbtFloat, 3); + TType *float4 = new TType(EbtFloat, 4); + + emu->addEmulatedFunction(EOpIsNan, float1, + "bool webgl_isnan_emu(float x)\n" + "{\n" + " return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n" + "}\n" + "\n"); + + emu->addEmulatedFunction(EOpIsNan, float2, + "bool2 webgl_isnan_emu(float2 x)\n" + "{\n" + " bool2 isnan;\n" + " for (int i = 0; i < 2; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); + + emu->addEmulatedFunction(EOpIsNan, float3, + "bool3 webgl_isnan_emu(float3 x)\n" + "{\n" + " bool3 isnan;\n" + " for (int i = 0; i < 3; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); + + emu->addEmulatedFunction(EOpIsNan, float4, + "bool4 webgl_isnan_emu(float4 x)\n" + "{\n" + " bool4 isnan;\n" + " for (int i = 0; i < 4; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); +} void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) { diff --git a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h index 4c45a93dc4f..f47449dfb26 100644 --- a/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h @@ -13,4 +13,10 @@ class BuiltInFunctionEmulator; void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu); +// +// This works around isnan() bug on some Intel drivers. +// +void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion); + #endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/CallDAG.cpp b/chromium/third_party/angle/src/compiler/translator/CallDAG.cpp index 10f0eb937c4..1c603ef8863 100644 --- a/chromium/third_party/angle/src/compiler/translator/CallDAG.cpp +++ b/chromium/third_party/angle/src/compiler/translator/CallDAG.cpp @@ -44,6 +44,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser skipped++; } } + ASSERT(mFunctions.size() == mCurrentIndex + skipped); return INITDAG_SUCCESS; } @@ -165,52 +166,102 @@ class CallDAG::CallDAGCreator : public TIntermTraverser } // Recursively assigns indices to a sub DAG - InitResult assignIndicesInternal(CreatorFunctionData *function) + InitResult assignIndicesInternal(CreatorFunctionData *root) { - ASSERT(function); + // Iterative implementation of the index assignment algorithm. A recursive version + // would be prettier but since the CallDAG creation runs before the limiting of the + // call depth, we might get stack overflows (computation of the call depth uses the + // CallDAG). - if (!function->node) - { - *mCreationInfo << "Undefined function '" << function->name - << ")' used in the following call chain:"; - return INITDAG_UNDEFINED; - } + ASSERT(root); - if (function->indexAssigned) + if (root->indexAssigned) { return INITDAG_SUCCESS; } - if (function->visiting) + // If we didn't have to detect recursion, functionsToProcess could be a simple queue + // in which we add the function being processed's callees. However in order to detect + // recursion we need to know which functions we are currently visiting. For that reason + // functionsToProcess will look like a concatenation of segments of the form + // [F visiting = true, subset of F callees with visiting = false] and the following + // segment (if any) will be start with a callee of F. + // This way we can remember when we started visiting a function, to put visiting back + // to false. + TVector<CreatorFunctionData *> functionsToProcess; + functionsToProcess.push_back(root); + + InitResult result = INITDAG_SUCCESS; + + while (!functionsToProcess.empty()) { - if (mCreationInfo) + CreatorFunctionData *function = functionsToProcess.back(); + + if (function->visiting) + { + function->visiting = false; + function->index = mCurrentIndex++; + function->indexAssigned = true; + + functionsToProcess.pop_back(); + continue; + } + + if (!function->node) { - *mCreationInfo << "Recursive function call in the following call chain:" << function->name; + *mCreationInfo << "Undefined function '" << function->name + << ")' used in the following call chain:"; + result = INITDAG_UNDEFINED; + break; + } + + if (function->indexAssigned) + { + functionsToProcess.pop_back(); + continue; + } + + function->visiting = true; + + for (auto callee : function->callees) + { + functionsToProcess.push_back(callee); + + // Check if the callee is already being visited after pushing it so that it appears + // in the chain printed in the info log. + if (callee->visiting) + { + *mCreationInfo << "Recursive function call in the following call chain:"; + result = INITDAG_RECURSION; + break; + } + } + + if (result != INITDAG_SUCCESS) + { + break; } - return INITDAG_RECURSION; } - function->visiting = true; - for (auto &callee : function->callees) + // The call chain is made of the function we were visiting when the error was detected. + if (result != INITDAG_SUCCESS) { - InitResult result = assignIndicesInternal(callee); - if (result != INITDAG_SUCCESS) + bool first = true; + for (auto function : functionsToProcess) { - // We know that there is an issue with the call chain in the AST, - // print the link of the chain we were processing. - if (mCreationInfo) + if (function->visiting) { - *mCreationInfo << " <- " << function->name << ")"; + if (!first) + { + *mCreationInfo << " -> "; + } + *mCreationInfo << function->name << ")"; + first = false; } - return result; } } - function->index = mCurrentIndex++; - function->indexAssigned = true; - - function->visiting = false; - return INITDAG_SUCCESS; + return result; } TInfoSinkBase *mCreationInfo; @@ -276,6 +327,8 @@ void CallDAG::clear() CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info) { + ASSERT(info); + CallDAGCreator creator(info); // Creates the mapping of functions to callees diff --git a/chromium/third_party/angle/src/compiler/translator/Compiler.cpp b/chromium/third_party/angle/src/compiler/translator/Compiler.cpp index 3c7742a68a0..547c09b1c46 100644 --- a/chromium/third_party/angle/src/compiler/translator/Compiler.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Compiler.cpp @@ -4,10 +4,18 @@ // found in the LICENSE file. // -#include "compiler/translator/Cache.h" #include "compiler/translator/Compiler.h" + +#include <sstream> + +#include "angle_gl.h" +#include "common/utilities.h" +#include "compiler/translator/AddAndTrueToLoopCondition.h" +#include "compiler/translator/Cache.h" #include "compiler/translator/CallDAG.h" #include "compiler/translator/DeferGlobalInitializers.h" +#include "compiler/translator/EmulateGLFragColorBroadcast.h" +#include "compiler/translator/EmulatePrecision.h" #include "compiler/translator/ForLoopUnroll.h" #include "compiler/translator/Initialize.h" #include "compiler/translator/InitializeParseContext.h" @@ -16,7 +24,6 @@ #include "compiler/translator/PruneEmptyDeclarations.h" #include "compiler/translator/RegenerateStructNames.h" #include "compiler/translator/RemovePow.h" -#include "compiler/translator/RenameFunction.h" #include "compiler/translator/RewriteDoWhile.h" #include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h" #include "compiler/translator/UnfoldShortCircuitAST.h" @@ -24,19 +31,49 @@ #include "compiler/translator/ValidateMaxParameters.h" #include "compiler/translator/ValidateOutputs.h" #include "compiler/translator/VariablePacker.h" -#include "compiler/translator/depgraph/DependencyGraph.h" -#include "compiler/translator/depgraph/DependencyGraphOutput.h" -#include "compiler/translator/timing/RestrictFragmentShaderTiming.h" -#include "compiler/translator/timing/RestrictVertexShaderTiming.h" #include "third_party/compiler/ArrayBoundsClamper.h" -#include "angle_gl.h" -#include "common/utilities.h" + +namespace +{ + +#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) +void DumpFuzzerCase(char const *const *shaderStrings, + size_t numStrings, + uint32_t type, + uint32_t spec, + uint32_t output, + uint64_t options) +{ + static int fileIndex = 0; + + std::ostringstream o; + o << "corpus/" << fileIndex++ << ".sample"; + std::string s = o.str(); + + // Must match the input format of the fuzzer + FILE *f = fopen(s.c_str(), "w"); + fwrite(&type, sizeof(type), 1, f); + fwrite(&spec, sizeof(spec), 1, f); + fwrite(&output, sizeof(output), 1, f); + fwrite(&options, sizeof(options), 1, f); + + char zero[128 - 20] = {0}; + fwrite(&zero, 128 - 20, 1, f); + + for (size_t i = 0; i < numStrings; i++) + { + fwrite(shaderStrings[i], sizeof(char), strlen(shaderStrings[i]), f); + } + fwrite(&zero, 1, 1, f); + + fclose(f); +} +#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) +} // anonymous namespace bool IsWebGLBasedSpec(ShShaderSpec spec) { - return (spec == SH_WEBGL_SPEC || - spec == SH_CSS_SHADERS_SPEC || - spec == SH_WEBGL2_SPEC); + return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC); } bool IsGLSL130OrNewer(ShShaderOutput output) @@ -60,7 +97,6 @@ size_t GetGlobalMaxTokenSize(ShShaderSpec spec) switch (spec) { case SH_WEBGL_SPEC: - case SH_CSS_SHADERS_SPEC: return 256; default: return 1024; @@ -111,11 +147,13 @@ int MapSpecToShaderVersion(ShShaderSpec spec) { case SH_GLES2_SPEC: case SH_WEBGL_SPEC: - case SH_CSS_SHADERS_SPEC: return 100; case SH_GLES3_SPEC: case SH_WEBGL2_SPEC: return 300; + case SH_GLES3_1_SPEC: + case SH_WEBGL3_SPEC: + return 310; default: UNREACHABLE(); return 0; @@ -137,7 +175,8 @@ TShHandleBase::~TShHandleBase() } TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) - : shaderType(type), + : variablesCollected(false), + shaderType(type), shaderSpec(spec), outputType(output), maxUniformVectors(0), @@ -148,15 +187,17 @@ TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC), builtInFunctionEmulator(), mSourcePath(NULL), + mComputeShaderLocalSizeDeclared(false), mTemporaryIndex(0) { + mComputeShaderLocalSize.fill(1); } TCompiler::~TCompiler() { } -bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const +bool TCompiler::shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const { // If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API, // validate loop and indexing as well (to verify that the shader only uses minimal functionality @@ -191,15 +232,16 @@ bool TCompiler::Init(const ShBuiltInResources& resources) return true; } -TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[], - size_t numStrings, int compileOptions) +TIntermNode *TCompiler::compileTreeForTesting(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions) { return compileTreeImpl(shaderStrings, numStrings, compileOptions); } TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], size_t numStrings, - const int compileOptions) + const ShCompileOptions compileOptions) { clearResults(); @@ -217,8 +259,7 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], ++firstSource; } - TIntermediate intermediate(infoSink); - TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, + TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec, compileOptions, true, infoSink, getResources()); parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh); @@ -246,13 +287,13 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], if (success) { mPragma = parseContext.pragma(); - if (mPragma.stdgl.invariantAll) - { - symbolTable.setGlobalInvariant(); - } + symbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll); + + mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared(); + mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize(); root = parseContext.getTreeRoot(); - root = intermediate.postProcess(root); + root = TIntermediate::PostProcess(root); // Highp might have been auto-enabled based on shader version fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh(); @@ -289,11 +330,17 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], if (success && shouldRunLoopAndIndexingValidation(compileOptions)) success = validateLimitations(root); - if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) - success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); - - if (success && shaderSpec == SH_CSS_SHADERS_SPEC) - rewriteCSSShader(root); + // Fail compilation if precision emulation not supported. + if (success && getResources().WEBGL_debug_shader_precision && + getPragma().debugShaderPrecision) + { + if (!EmulatePrecision::SupportedInLanguage(outputType)) + { + infoSink.info.prefix(EPrefixError); + infoSink.info << "Precision emulation not supported for this output type."; + success = false; + } + } // Unroll for-loop markup needs to happen after validateLimitations pass. if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) @@ -339,6 +386,9 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS)) RewriteDoWhile(root, getTemporaryIndex()); + if (success && (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION)) + sh::AddAndTrueToLoopCondition(root); + if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) { UnfoldShortCircuitAST unfoldShortCircuit; @@ -363,9 +413,10 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], infoSink.info << "too many uniforms"; } } - if (success && shaderType == GL_VERTEX_SHADER && - (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE)) - initializeVaryingsWithoutStaticUse(root); + if (success && (compileOptions & SH_INIT_OUTPUT_VARIABLES)) + { + initializeOutputVariables(root); + } } if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)) @@ -381,6 +432,13 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], root->traverse(&gen); } + if (success && shaderType == GL_FRAGMENT_SHADER && shaderVersion == 100 && + compileResources.EXT_draw_buffers && compileResources.MaxDrawBuffers > 1 && + IsExtensionEnabled(extensionBehavior, "GL_EXT_draw_buffers")) + { + EmulateGLFragColorBroadcast(root, compileResources.MaxDrawBuffers, &outputVariables); + } + if (success) { DeferGlobalInitializers(root); @@ -394,12 +452,26 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], return NULL; } -bool TCompiler::compile(const char* const shaderStrings[], - size_t numStrings, int compileOptions) +bool TCompiler::compile(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptionsIn) { +#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) + DumpFuzzerCase(shaderStrings, numStrings, shaderType, shaderSpec, outputType, compileOptionsIn); +#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) + if (numStrings == 0) return true; + ShCompileOptions compileOptions = compileOptionsIn; + + // Apply key workarounds. + if (shouldFlattenPragmaStdglInvariantAll()) + { + // This should be harmless to do in all cases, but for the moment, do it only conditionally. + compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL; + } + TScopedPoolAllocator scopedAlloc(&allocator); TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions); @@ -427,17 +499,16 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) symbolTable.push(); // COMMON_BUILTINS symbolTable.push(); // ESSL1_BUILTINS symbolTable.push(); // ESSL3_BUILTINS + symbolTable.push(); // ESSL3_1_BUILTINS TPublicType integer; - integer.type = EbtInt; - integer.primarySize = 1; - integer.secondarySize = 1; + integer.setBasicType(EbtInt); + integer.initializeSizeForScalarTypes(); integer.array = false; TPublicType floatingPoint; - floatingPoint.type = EbtFloat; - floatingPoint.primarySize = 1; - floatingPoint.secondarySize = 1; + floatingPoint.setBasicType(EbtFloat); + floatingPoint.initializeSizeForScalarTypes(); floatingPoint.array = false; switch(shaderType) @@ -449,6 +520,10 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) symbolTable.setDefaultPrecision(integer, EbpHigh); symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); break; + case GL_COMPUTE_SHADER: + symbolTable.setDefaultPrecision(integer, EbpHigh); + symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); + break; default: assert(false && "Language not supported"); } @@ -473,10 +548,9 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType) { ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd); TPublicType sampler; - sampler.primarySize = 1; - sampler.secondarySize = 1; + sampler.initializeSizeForScalarTypes(); + sampler.setBasicType(samplerType); sampler.array = false; - sampler.type = samplerType; symbolTable.setDefaultPrecision(sampler, EbpLow); } @@ -515,7 +589,31 @@ void TCompiler::setResourceString() << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers << ":NV_draw_buffers:" << compileResources.NV_draw_buffers - << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision; + << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision + << ":MaxImageUnits:" << compileResources.MaxImageUnits + << ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms + << ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms + << ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms + << ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms + << ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources + << ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0] + << ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1] + << ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2] + << ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0] + << ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1] + << ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2] + << ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents + << ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits + << ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters + << ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers + << ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters + << ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters + << ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters + << ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings + << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers + << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers + << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers + << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize; // clang-format on builtInResourcesString = strstream.str(); @@ -534,6 +632,7 @@ void TCompiler::clearResults() expandedUniforms.clear(); varyings.clear(); interfaceBlocks.clear(); + variablesCollected = false; builtInFunctionEmulator.Cleanup(); @@ -711,12 +810,6 @@ bool TCompiler::validateOutputs(TIntermNode* root) return (validateOutputs.validateAndCountErrors(infoSink.info) == 0); } -void TCompiler::rewriteCSSShader(TIntermNode* root) -{ - RenameFunction renamer("main(", "css_main("); - root->traverse(&renamer); -} - bool TCompiler::validateLimitations(TIntermNode* root) { ValidateLimitations validate(shaderType, &infoSink.info); @@ -724,36 +817,6 @@ bool TCompiler::validateLimitations(TIntermNode* root) return validate.numErrors() == 0; } -bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph) -{ - if (shaderSpec != SH_WEBGL_SPEC) - { - infoSink.info << "Timing restrictions must be enforced under the WebGL spec."; - return false; - } - - if (shaderType == GL_FRAGMENT_SHADER) - { - TDependencyGraph graph(root); - - // Output any errors first. - bool success = enforceFragmentShaderTimingRestrictions(graph); - - // Then, output the dependency graph. - if (outputGraph) - { - TDependencyGraphOutput output(infoSink.info); - output.outputAllSpanningTrees(graph); - } - - return success; - } - else - { - return enforceVertexShaderTimingRestrictions(root); - } -} - bool TCompiler::limitExpressionComplexity(TIntermNode* root) { TMaxDepthTraverser traverser(maxExpressionComplexity+1); @@ -774,33 +837,18 @@ bool TCompiler::limitExpressionComplexity(TIntermNode* root) return true; } -bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph) -{ - RestrictFragmentShaderTiming restrictor(infoSink.info); - restrictor.enforceRestrictions(graph); - return restrictor.numErrors() == 0; -} - -bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root) -{ - RestrictVertexShaderTiming restrictor(infoSink.info); - restrictor.enforceRestrictions(root); - return restrictor.numErrors() == 0; -} - void TCompiler::collectVariables(TIntermNode* root) { - sh::CollectVariables collect(&attributes, - &outputVariables, - &uniforms, - &varyings, - &interfaceBlocks, - hashFunction, - symbolTable); - root->traverse(&collect); + if (!variablesCollected) + { + sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings, + &interfaceBlocks, hashFunction, symbolTable, extensionBehavior); + root->traverse(&collect); - // This is for enforcePackingRestriction(). - sh::ExpandUniforms(uniforms, &expandedUniforms); + // This is for enforcePackingRestriction(). + sh::ExpandUniforms(uniforms, &expandedUniforms); + variablesCollected = true; + } } bool TCompiler::enforcePackingRestrictions() @@ -811,37 +859,32 @@ bool TCompiler::enforcePackingRestrictions() void TCompiler::initializeGLPosition(TIntermNode* root) { - InitializeVariables::InitVariableInfoList variables; - InitializeVariables::InitVariableInfo var( - "gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4)); - variables.push_back(var); - InitializeVariables initializer(variables); - root->traverse(&initializer); + InitVariableList list; + sh::ShaderVariable var(GL_FLOAT_VEC4, 0); + var.name = "gl_Position"; + list.push_back(var); + InitializeVariables(root, list); } -void TCompiler::initializeVaryingsWithoutStaticUse(TIntermNode* root) +void TCompiler::initializeOutputVariables(TIntermNode *root) { - InitializeVariables::InitVariableInfoList variables; - for (size_t ii = 0; ii < varyings.size(); ++ii) + InitVariableList list; + if (shaderType == GL_VERTEX_SHADER) { - const sh::Varying& varying = varyings[ii]; - if (varying.staticUse) - continue; - unsigned char primarySize = static_cast<unsigned char>(gl::VariableColumnCount(varying.type)); - unsigned char secondarySize = static_cast<unsigned char>(gl::VariableRowCount(varying.type)); - TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray()); - TString name = varying.name.c_str(); - if (varying.isArray()) + for (auto var : varyings) { - type.setArraySize(varying.arraySize); - name = name.substr(0, name.find_first_of('[')); + list.push_back(var); } - - InitializeVariables::InitVariableInfo var(name, type); - variables.push_back(var); } - InitializeVariables initializer(variables); - root->traverse(&initializer); + else + { + ASSERT(shaderType == GL_FRAGMENT_SHADER); + for (auto var : outputVariables) + { + list.push_back(var); + } + } + InitializeVariables(root, list); } const TExtensionBehavior& TCompiler::getExtensionBehavior() const @@ -874,9 +917,26 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const return builtInFunctionEmulator; } -void TCompiler::writePragma() +void TCompiler::writePragma(ShCompileOptions compileOptions) +{ + if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL)) + { + TInfoSinkBase &sink = infoSink.obj; + if (mPragma.stdgl.invariantAll) + sink << "#pragma STDGL invariant(all)\n"; + } +} + +bool TCompiler::isVaryingDefined(const char *varyingName) { - TInfoSinkBase &sink = infoSink.obj; - if (mPragma.stdgl.invariantAll) - sink << "#pragma STDGL invariant(all)\n"; + ASSERT(variablesCollected); + for (size_t ii = 0; ii < varyings.size(); ++ii) + { + if (varyings[ii].name == varyingName) + { + return true; + } + } + + return false; } diff --git a/chromium/third_party/angle/src/compiler/translator/Compiler.h b/chromium/third_party/angle/src/compiler/translator/Compiler.h index 99c155c33df..ace1abbaef6 100644 --- a/chromium/third_party/angle/src/compiler/translator/Compiler.h +++ b/chromium/third_party/angle/src/compiler/translator/Compiler.h @@ -25,14 +25,12 @@ #include "third_party/compiler/ArrayBoundsClamper.h" class TCompiler; -class TDependencyGraph; #ifdef ANGLE_ENABLE_HLSL class TranslatorHLSL; #endif // ANGLE_ENABLE_HLSL // -// Helper function to identify specs that are based on the WebGL spec, -// like the CSS Shaders spec. +// Helper function to identify specs that are based on the WebGL spec. // bool IsWebGLBasedSpec(ShShaderSpec spec); @@ -75,16 +73,21 @@ class TCompiler : public TShHandleBase // compileTreeForTesting should be used only when tests require access to // the AST. Users of this function need to manually manage the global pool // allocator. Returns NULL whenever there are compilation errors. - TIntermNode *compileTreeForTesting(const char* const shaderStrings[], - size_t numStrings, int compileOptions); + TIntermNode *compileTreeForTesting(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions); - bool compile(const char* const shaderStrings[], - size_t numStrings, int compileOptions); + bool compile(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions); // Get results of the last compilation. int getShaderVersion() const { return shaderVersion; } TInfoSink& getInfoSink() { return infoSink; } + bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } + const sh::WorkGroupSize &getComputeShaderLocalSize() { return mComputeShaderLocalSize; } + // Clears the results from the previous compilation. void clearResults(); @@ -101,7 +104,7 @@ class TCompiler : public TShHandleBase ShShaderOutput getOutputType() const { return outputType; } const std::string &getBuiltInResourcesString() const { return builtInResourcesString; } - bool shouldRunLoopAndIndexingValidation(int compileOptions) const; + bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const; // Get the resources set by InitBuiltInSymbolTable const ShBuiltInResources& getResources() const; @@ -116,61 +119,56 @@ class TCompiler : public TShHandleBase bool checkCallDepth(); // Returns true if a program has no conflicting or missing fragment outputs bool validateOutputs(TIntermNode* root); - // Rewrites a shader's intermediate tree according to the CSS Shaders spec. - void rewriteCSSShader(TIntermNode* root); // Returns true if the given shader does not exceed the minimum // functionality mandated in GLSL 1.0 spec Appendix A. bool validateLimitations(TIntermNode* root); // Collect info for all attribs, uniforms, varyings. void collectVariables(TIntermNode* root); // Add emulated functions to the built-in function emulator. - virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {}; + virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions){}; // Translate to object code. - virtual void translate(TIntermNode *root, int compileOptions) = 0; + virtual void translate(TIntermNode *root, ShCompileOptions compileOptions) = 0; // Returns true if, after applying the packing rules in the GLSL 1.017 spec // Appendix A, section 7, the shader does not use too many uniforms. bool enforcePackingRestrictions(); - // Insert statements to initialize varyings without static use in the beginning - // of main(). It is to work around a Mac driver where such varyings in a vertex - // shader may be optimized out incorrectly at compile time, causing a link failure. - // This function should only be applied to vertex shaders. - void initializeVaryingsWithoutStaticUse(TIntermNode* root); + // Insert statements to initialize output variables in the beginning of main(). + // This is to avoid undefined behaviors. + void initializeOutputVariables(TIntermNode *root); // Insert gl_Position = vec4(0,0,0,0) to the beginning of main(). // It is to work around a Linux driver bug where missing this causes compile failure // while spec says it is allowed. // This function should only be applied to vertex shaders. void initializeGLPosition(TIntermNode* root); - // Returns true if the shader passes the restrictions that aim to prevent timing attacks. - bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph); - // Returns true if the shader does not use samplers. - bool enforceVertexShaderTimingRestrictions(TIntermNode* root); - // Returns true if the shader does not use sampler dependent values to affect control - // flow or in operations whose time can depend on the input values. - bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph); // Return true if the maximum expression complexity is below the limit. bool limitExpressionComplexity(TIntermNode* root); // Get built-in extensions with default behavior. const TExtensionBehavior& getExtensionBehavior() const; const char *getSourcePath() const; const TPragma& getPragma() const { return mPragma; } - void writePragma(); + void writePragma(ShCompileOptions compileOptions); unsigned int *getTemporaryIndex() { return &mTemporaryIndex; } + // Relies on collectVariables having been called. + bool isVaryingDefined(const char *varyingName); const ArrayBoundsClamper& getArrayBoundsClamper() const; ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const; const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const; + virtual bool shouldCollectVariables(ShCompileOptions compileOptions) + { + return (compileOptions & SH_VARIABLES) != 0; + } + + virtual bool shouldFlattenPragmaStdglInvariantAll() = 0; + std::vector<sh::Attribute> attributes; std::vector<sh::OutputVariable> outputVariables; std::vector<sh::Uniform> uniforms; std::vector<sh::ShaderVariable> expandedUniforms; std::vector<sh::Varying> varyings; std::vector<sh::InterfaceBlock> interfaceBlocks; - - virtual bool shouldCollectVariables(int compileOptions) - { - return (compileOptions & SH_VARIABLES) != 0; - } + bool variablesCollected; private: // Creates the function call DAG for further analysis, returning false if there is a recursion @@ -187,7 +185,7 @@ class TCompiler : public TShHandleBase TIntermNode *compileTreeImpl(const char *const shaderStrings[], size_t numStrings, - const int compileOptions); + const ShCompileOptions compileOptions); sh::GLenum shaderType; ShShaderSpec shaderSpec; @@ -229,6 +227,10 @@ class TCompiler : public TShHandleBase TInfoSink infoSink; // Output sink. const char *mSourcePath; // Path of source file or NULL + // compute shader local group size + bool mComputeShaderLocalSizeDeclared; + sh::WorkGroupSize mComputeShaderLocalSize; + // name hashing. ShHashFunction64 hashFunction; NameMap nameMap; diff --git a/chromium/third_party/angle/src/compiler/translator/ConstantUnion.cpp b/chromium/third_party/angle/src/compiler/translator/ConstantUnion.cpp new file mode 100644 index 00000000000..10a70f34ec8 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ConstantUnion.cpp @@ -0,0 +1,590 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ConstantUnion: Constant folding helper class. + +#include "compiler/translator/ConstantUnion.h" + +#include "base/numerics/safe_math.h" +#include "common/mathutil.h" +#include "compiler/translator/Diagnostics.h" + +namespace +{ + +template <typename T> +T CheckedSum(base::CheckedNumeric<T> lhs, + base::CheckedNumeric<T> rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + ASSERT(lhs.IsValid() && rhs.IsValid()); + auto result = lhs + rhs; + if (!result.IsValid()) + { + diag->error(line, "Addition out of range", "*", ""); + return 0; + } + return result.ValueOrDefault(0); +} + +template <typename T> +T CheckedDiff(base::CheckedNumeric<T> lhs, + base::CheckedNumeric<T> rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + ASSERT(lhs.IsValid() && rhs.IsValid()); + auto result = lhs - rhs; + if (!result.IsValid()) + { + diag->error(line, "Difference out of range", "*", ""); + return 0; + } + return result.ValueOrDefault(0); +} + +template <typename T> +T CheckedMul(base::CheckedNumeric<T> lhs, + base::CheckedNumeric<T> rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + ASSERT(lhs.IsValid() && rhs.IsValid()); + auto result = lhs * rhs; + if (!result.IsValid()) + { + diag->error(line, "Multiplication out of range", "*", ""); + return 0; + } + return result.ValueOrDefault(0); +} + +} // anonymous namespace + +TConstantUnion::TConstantUnion() +{ + iConst = 0; + type = EbtVoid; +} + +bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant) +{ + switch (newType) + { + case EbtFloat: + switch (constant.type) + { + case EbtInt: + setFConst(static_cast<float>(constant.getIConst())); + break; + case EbtUInt: + setFConst(static_cast<float>(constant.getUConst())); + break; + case EbtBool: + setFConst(static_cast<float>(constant.getBConst())); + break; + case EbtFloat: + setFConst(static_cast<float>(constant.getFConst())); + break; + default: + return false; + } + break; + case EbtInt: + switch (constant.type) + { + case EbtInt: + setIConst(static_cast<int>(constant.getIConst())); + break; + case EbtUInt: + setIConst(static_cast<int>(constant.getUConst())); + break; + case EbtBool: + setIConst(static_cast<int>(constant.getBConst())); + break; + case EbtFloat: + setIConst(static_cast<int>(constant.getFConst())); + break; + default: + return false; + } + break; + case EbtUInt: + switch (constant.type) + { + case EbtInt: + setUConst(static_cast<unsigned int>(constant.getIConst())); + break; + case EbtUInt: + setUConst(static_cast<unsigned int>(constant.getUConst())); + break; + case EbtBool: + setUConst(static_cast<unsigned int>(constant.getBConst())); + break; + case EbtFloat: + setUConst(static_cast<unsigned int>(constant.getFConst())); + break; + default: + return false; + } + break; + case EbtBool: + switch (constant.type) + { + case EbtInt: + setBConst(constant.getIConst() != 0); + break; + case EbtUInt: + setBConst(constant.getUConst() != 0); + break; + case EbtBool: + setBConst(constant.getBConst()); + break; + case EbtFloat: + setBConst(constant.getFConst() != 0.0f); + break; + default: + return false; + } + break; + case EbtStruct: // Struct fields don't get cast + switch (constant.type) + { + case EbtInt: + setIConst(constant.getIConst()); + break; + case EbtUInt: + setUConst(constant.getUConst()); + break; + case EbtBool: + setBConst(constant.getBConst()); + break; + case EbtFloat: + setFConst(constant.getFConst()); + break; + default: + return false; + } + break; + default: + return false; + } + + return true; +} + +bool TConstantUnion::operator==(const int i) const +{ + return i == iConst; +} + +bool TConstantUnion::operator==(const unsigned int u) const +{ + return u == uConst; +} + +bool TConstantUnion::operator==(const float f) const +{ + return f == fConst; +} + +bool TConstantUnion::operator==(const bool b) const +{ + return b == bConst; +} + +bool TConstantUnion::operator==(const TConstantUnion &constant) const +{ + if (constant.type != type) + return false; + + switch (type) + { + case EbtInt: + return constant.iConst == iConst; + case EbtUInt: + return constant.uConst == uConst; + case EbtFloat: + return constant.fConst == fConst; + case EbtBool: + return constant.bConst == bConst; + default: + return false; + } +} + +bool TConstantUnion::operator!=(const int i) const +{ + return !operator==(i); +} + +bool TConstantUnion::operator!=(const unsigned int u) const +{ + return !operator==(u); +} + +bool TConstantUnion::operator!=(const float f) const +{ + return !operator==(f); +} + +bool TConstantUnion::operator!=(const bool b) const +{ + return !operator==(b); +} + +bool TConstantUnion::operator!=(const TConstantUnion &constant) const +{ + return !operator==(constant); +} + +bool TConstantUnion::operator>(const TConstantUnion &constant) const +{ + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + return iConst > constant.iConst; + case EbtUInt: + return uConst > constant.uConst; + case EbtFloat: + return fConst > constant.fConst; + default: + return false; // Invalid operation, handled at semantic analysis + } +} + +bool TConstantUnion::operator<(const TConstantUnion &constant) const +{ + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + return iConst < constant.iConst; + case EbtUInt: + return uConst < constant.uConst; + case EbtFloat: + return fConst < constant.fConst; + default: + return false; // Invalid operation, handled at semantic analysis + } +} + +// static +TConstantUnion TConstantUnion::add(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == rhs.type); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(gl::WrappingSum<int>(lhs.iConst, rhs.iConst)); + break; + case EbtUInt: + returnValue.setUConst(gl::WrappingSum<unsigned int>(lhs.uConst, rhs.uConst)); + break; + case EbtFloat: + returnValue.setFConst(CheckedSum<float>(lhs.fConst, rhs.fConst, diag, line)); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +// static +TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == rhs.type); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(gl::WrappingDiff<int>(lhs.iConst, rhs.iConst)); + break; + case EbtUInt: + returnValue.setUConst(gl::WrappingDiff<unsigned int>(lhs.uConst, rhs.uConst)); + break; + case EbtFloat: + returnValue.setFConst(CheckedDiff<float>(lhs.fConst, rhs.fConst, diag, line)); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +// static +TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == rhs.type); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst)); + break; + case EbtUInt: + // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that + // to implement wrapping multiplication. + returnValue.setUConst(lhs.uConst * rhs.uConst); + break; + case EbtFloat: + returnValue.setFConst(CheckedMul<float>(lhs.fConst, rhs.fConst, diag, line)); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst % constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst % constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +// static +TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt); + ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt); + if ((lhs.type == EbtInt && lhs.iConst < 0) || + (rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) || + (rhs.type == EbtUInt && rhs.uConst > 31)) + { + diag->error(line, "Undefined shift (operand out of range)", ">>", ""); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(0); + break; + case EbtUInt: + returnValue.setUConst(0u); + break; + default: + UNREACHABLE(); + } + return returnValue; + } + + switch (lhs.type) + { + case EbtInt: + switch (rhs.type) + { + case EbtInt: + returnValue.setIConst(lhs.iConst >> rhs.iConst); + break; + case EbtUInt: + returnValue.setIConst(lhs.iConst >> rhs.uConst); + break; + default: + UNREACHABLE(); + } + break; + + case EbtUInt: + switch (rhs.type) + { + case EbtInt: + returnValue.setUConst(lhs.uConst >> rhs.iConst); + break; + case EbtUInt: + returnValue.setUConst(lhs.uConst >> rhs.uConst); + break; + default: + UNREACHABLE(); + } + break; + + default: + UNREACHABLE(); + } + return returnValue; +} + +// static +TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt); + ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt); + if ((lhs.type == EbtInt && lhs.iConst < 0) || + (rhs.type == EbtInt && (rhs.iConst < 0 || rhs.iConst > 31)) || + (rhs.type == EbtUInt && rhs.uConst > 31)) + { + diag->error(line, "Undefined shift (operand out of range)", "<<", ""); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(0); + break; + case EbtUInt: + returnValue.setUConst(0u); + break; + default: + UNREACHABLE(); + } + return returnValue; + } + + switch (lhs.type) + { + case EbtInt: + switch (rhs.type) + { + case EbtInt: + returnValue.setIConst(lhs.iConst << rhs.iConst); + break; + case EbtUInt: + returnValue.setIConst(lhs.iConst << rhs.uConst); + break; + default: + UNREACHABLE(); + } + break; + + case EbtUInt: + switch (rhs.type) + { + case EbtInt: + returnValue.setUConst(lhs.uConst << rhs.iConst); + break; + case EbtUInt: + returnValue.setUConst(lhs.uConst << rhs.uConst); + break; + default: + UNREACHABLE(); + } + break; + + default: + UNREACHABLE(); + } + return returnValue; +} + +TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(constant.type == EbtInt || constant.type == EbtUInt); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst & constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst & constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst | constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst | constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst ^ constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst ^ constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtBool: + returnValue.setBConst(bConst && constant.bConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtBool: + returnValue.setBConst(bConst || constant.bConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} diff --git a/chromium/third_party/angle/src/compiler/translator/ConstantUnion.h b/chromium/third_party/angle/src/compiler/translator/ConstantUnion.h index a86d27f3ff3..eec0f0ff97d 100644 --- a/chromium/third_party/angle/src/compiler/translator/ConstantUnion.h +++ b/chromium/third_party/angle/src/compiler/translator/ConstantUnion.h @@ -9,77 +9,18 @@ #include <assert.h> +#include "compiler/translator/Common.h" #include "compiler/translator/BaseTypes.h" -class TConstantUnion { -public: - POOL_ALLOCATOR_NEW_DELETE(); - TConstantUnion() - { - iConst = 0; - type = EbtVoid; - } +class TDiagnostics; - bool cast(TBasicType newType, const TConstantUnion &constant) - { - switch (newType) - { - case EbtFloat: - switch (constant.type) - { - case EbtInt: setFConst(static_cast<float>(constant.getIConst())); break; - case EbtUInt: setFConst(static_cast<float>(constant.getUConst())); break; - case EbtBool: setFConst(static_cast<float>(constant.getBConst())); break; - case EbtFloat: setFConst(static_cast<float>(constant.getFConst())); break; - default: return false; - } - break; - case EbtInt: - switch (constant.type) - { - case EbtInt: setIConst(static_cast<int>(constant.getIConst())); break; - case EbtUInt: setIConst(static_cast<int>(constant.getUConst())); break; - case EbtBool: setIConst(static_cast<int>(constant.getBConst())); break; - case EbtFloat: setIConst(static_cast<int>(constant.getFConst())); break; - default: return false; - } - break; - case EbtUInt: - switch (constant.type) - { - case EbtInt: setUConst(static_cast<unsigned int>(constant.getIConst())); break; - case EbtUInt: setUConst(static_cast<unsigned int>(constant.getUConst())); break; - case EbtBool: setUConst(static_cast<unsigned int>(constant.getBConst())); break; - case EbtFloat: setUConst(static_cast<unsigned int>(constant.getFConst())); break; - default: return false; - } - break; - case EbtBool: - switch (constant.type) - { - case EbtInt: setBConst(constant.getIConst() != 0); break; - case EbtUInt: setBConst(constant.getUConst() != 0); break; - case EbtBool: setBConst(constant.getBConst()); break; - case EbtFloat: setBConst(constant.getFConst() != 0.0f); break; - default: return false; - } - break; - case EbtStruct: // Struct fields don't get cast - switch (constant.type) - { - case EbtInt: setIConst(constant.getIConst()); break; - case EbtUInt: setUConst(constant.getUConst()); break; - case EbtBool: setBConst(constant.getBConst()); break; - case EbtFloat: setFConst(constant.getFConst()); break; - default: return false; - } - break; - default: - return false; - } +class TConstantUnion +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TConstantUnion(); - return true; - } + bool cast(TBasicType newType, const TConstantUnion &constant); void setIConst(int i) {iConst = i; type = EbtInt; } void setUConst(unsigned int u) { uConst = u; type = EbtUInt; } @@ -91,256 +32,53 @@ public: float getFConst() const { return fConst; } bool getBConst() const { return bConst; } - bool operator==(const int i) const - { - return i == iConst; - } - - bool operator==(const unsigned int u) const - { - return u == uConst; - } - - bool operator==(const float f) const - { - return f == fConst; - } - - bool operator==(const bool b) const - { - return b == bConst; - } - - bool operator==(const TConstantUnion& constant) const - { - if (constant.type != type) - return false; - - switch (type) { - case EbtInt: - return constant.iConst == iConst; - case EbtUInt: - return constant.uConst == uConst; - case EbtFloat: - return constant.fConst == fConst; - case EbtBool: - return constant.bConst == bConst; - default: - return false; - } - } - - bool operator!=(const int i) const - { - return !operator==(i); - } - - bool operator!=(const unsigned int u) const - { - return !operator==(u); - } - - bool operator!=(const float f) const - { - return !operator==(f); - } - - bool operator!=(const bool b) const - { - return !operator==(b); - } - - bool operator!=(const TConstantUnion& constant) const - { - return !operator==(constant); - } - - bool operator>(const TConstantUnion& constant) const - { - assert(type == constant.type); - switch (type) { - case EbtInt: - return iConst > constant.iConst; - case EbtUInt: - return uConst > constant.uConst; - case EbtFloat: - return fConst > constant.fConst; - default: - return false; // Invalid operation, handled at semantic analysis - } - } - - bool operator<(const TConstantUnion& constant) const - { - assert(type == constant.type); - switch (type) { - case EbtInt: - return iConst < constant.iConst; - case EbtUInt: - return uConst < constant.uConst; - case EbtFloat: - return fConst < constant.fConst; - default: - return false; // Invalid operation, handled at semantic analysis - } - } - - TConstantUnion operator+(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break; - case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator-(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break; - case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator*(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break; - case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator%(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator>>(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator<<(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - // The signedness of the second parameter might be different, but we - // don't care, since the result is undefined if the second parameter is - // negative, and aliasing should not be a problem with unions. - assert(constant.type == EbtInt || constant.type == EbtUInt); - switch (type) { - case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator&(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(constant.type == EbtInt || constant.type == EbtUInt); - switch (type) { - case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator|(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator^(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator&&(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtBool: returnValue.setBConst(bConst && constant.bConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator||(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtBool: returnValue.setBConst(bConst || constant.bConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } + bool operator==(const int i) const; + bool operator==(const unsigned int u) const; + bool operator==(const float f) const; + bool operator==(const bool b) const; + bool operator==(const TConstantUnion &constant) const; + bool operator!=(const int i) const; + bool operator!=(const unsigned int u) const; + bool operator!=(const float f) const; + bool operator!=(const bool b) const; + bool operator!=(const TConstantUnion &constant) const; + bool operator>(const TConstantUnion &constant) const; + bool operator<(const TConstantUnion &constant) const; + static TConstantUnion add(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + static TConstantUnion sub(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + static TConstantUnion mul(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + TConstantUnion operator%(const TConstantUnion &constant) const; + static TConstantUnion rshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + static TConstantUnion lshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + TConstantUnion operator&(const TConstantUnion &constant) const; + TConstantUnion operator|(const TConstantUnion &constant) const; + TConstantUnion operator^(const TConstantUnion &constant) const; + TConstantUnion operator&&(const TConstantUnion &constant) const; + TConstantUnion operator||(const TConstantUnion &constant) const; TBasicType getType() const { return type; } -private: - - union { - int iConst; // used for ivec, scalar ints - unsigned int uConst; // used for uvec, scalar uints - bool bConst; // used for bvec, scalar bools - float fConst; // used for vec, mat, scalar floats - } ; + private: + union { + int iConst; // used for ivec, scalar ints + unsigned int uConst; // used for uvec, scalar uints + bool bConst; // used for bvec, scalar bools + float fConst; // used for vec, mat, scalar floats + }; TBasicType type; }; diff --git a/chromium/third_party/angle/src/compiler/translator/DeferGlobalInitializers.cpp b/chromium/third_party/angle/src/compiler/translator/DeferGlobalInitializers.cpp index 6904f9401a1..285aa183b0a 100644 --- a/chromium/third_party/angle/src/compiler/translator/DeferGlobalInitializers.cpp +++ b/chromium/third_party/angle/src/compiler/translator/DeferGlobalInitializers.cpp @@ -101,10 +101,8 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n // Deferral is done also in any cases where the variable has not been constant folded, // since otherwise there's a chance that HLSL output will generate extra statements // from the initializer expression. - TIntermBinary *deferredInit = new TIntermBinary(EOpAssign); - deferredInit->setLeft(symbolNode->deepCopy()); - deferredInit->setRight(node->getRight()); - deferredInit->setType(node->getType()); + TIntermBinary *deferredInit = + new TIntermBinary(EOpAssign, symbolNode->deepCopy(), node->getRight()); mDeferredInitializers.push_back(deferredInit); // Change const global to a regular global if its initialization is deferred. @@ -130,7 +128,7 @@ bool DeferGlobalInitializersTraverser::visitBinary(Visit visit, TIntermBinary *n ASSERT(symbolNode->getQualifier() == EvqGlobal); } // Remove the initializer from the global scope and just declare the global instead. - mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, symbolNode, false)); + queueReplacement(node, symbolNode, OriginalNode::IS_DROPPED); } } return false; diff --git a/chromium/third_party/angle/src/compiler/translator/Diagnostics.cpp b/chromium/third_party/angle/src/compiler/translator/Diagnostics.cpp index 593137fb0ae..6ba4679c459 100644 --- a/chromium/third_party/angle/src/compiler/translator/Diagnostics.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Diagnostics.cpp @@ -7,8 +7,9 @@ #include "compiler/translator/Diagnostics.h" #include "common/debug.h" -#include "compiler/translator/InfoSink.h" #include "compiler/preprocessor/SourceLocation.h" +#include "compiler/translator/Common.h" +#include "compiler/translator/InfoSink.h" TDiagnostics::TDiagnostics(TInfoSink& infoSink) : mInfoSink(infoSink), @@ -50,6 +51,28 @@ void TDiagnostics::writeInfo(Severity severity, sink << "'" << token << "' : " << reason << " " << extra << "\n"; } +void TDiagnostics::error(const TSourceLoc &loc, + const char *reason, + const char *token, + const char *extraInfo) +{ + pp::SourceLocation srcLoc; + srcLoc.file = loc.first_file; + srcLoc.line = loc.first_line; + writeInfo(pp::Diagnostics::PP_ERROR, srcLoc, reason, token, extraInfo); +} + +void TDiagnostics::warning(const TSourceLoc &loc, + const char *reason, + const char *token, + const char *extraInfo) +{ + pp::SourceLocation srcLoc; + srcLoc.file = loc.first_file; + srcLoc.line = loc.first_line; + writeInfo(pp::Diagnostics::PP_WARNING, srcLoc, reason, token, extraInfo); +} + void TDiagnostics::print(ID id, const pp::SourceLocation& loc, const std::string& text) diff --git a/chromium/third_party/angle/src/compiler/translator/Diagnostics.h b/chromium/third_party/angle/src/compiler/translator/Diagnostics.h index bc26e4584fa..bb521da1a2a 100644 --- a/chromium/third_party/angle/src/compiler/translator/Diagnostics.h +++ b/chromium/third_party/angle/src/compiler/translator/Diagnostics.h @@ -11,6 +11,7 @@ #include "compiler/preprocessor/DiagnosticsBase.h" class TInfoSink; +struct TSourceLoc; class TDiagnostics : public pp::Diagnostics, angle::NonCopyable { @@ -29,6 +30,12 @@ class TDiagnostics : public pp::Diagnostics, angle::NonCopyable const std::string& token, const std::string& extra); + void error(const TSourceLoc &loc, const char *reason, const char *token, const char *extraInfo); + void warning(const TSourceLoc &loc, + const char *reason, + const char *token, + const char *extraInfo); + protected: void print(ID id, const pp::SourceLocation &loc, const std::string &text) override; diff --git a/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.cpp b/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.cpp index ff8a69efa52..f8081ecd659 100644 --- a/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.cpp +++ b/chromium/third_party/angle/src/compiler/translator/DirectiveHandler.cpp @@ -182,8 +182,7 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc, int version) { - if (version == 100 || - version == 300) + if (version == 100 || version == 300 || version == 310) { mShaderVersion = version; } diff --git a/chromium/third_party/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp b/chromium/third_party/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp new file mode 100644 index 00000000000..431a326a5af --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp @@ -0,0 +1,141 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// gl_FragColor needs to broadcast to all color buffers in ES2 if +// GL_EXT_draw_buffers is explicitly enabled in a fragment shader. +// +// We emulate this by replacing all gl_FragColor with gl_FragData[0], and in the end +// of main() function, assigning gl_FragData[1], ..., gl_FragData[maxDrawBuffers-1] +// with gl_FragData[0]. +// + +#include "compiler/translator/EmulateGLFragColorBroadcast.h" +#include "compiler/translator/IntermNode.h" + +namespace +{ + +class GLFragColorBroadcastTraverser : public TIntermTraverser +{ + public: + GLFragColorBroadcastTraverser(int maxDrawBuffers) + : TIntermTraverser(true, false, false), + mMainSequence(nullptr), + mGLFragColorUsed(false), + mMaxDrawBuffers(maxDrawBuffers) + { + } + + void broadcastGLFragColor(); + + bool isGLFragColorUsed() const { return mGLFragColorUsed; } + + protected: + void visitSymbol(TIntermSymbol *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + + TIntermBinary *constructGLFragDataNode(int index) const; + TIntermBinary *constructGLFragDataAssignNode(int index) const; + + private: + TIntermSequence *mMainSequence; + bool mGLFragColorUsed; + int mMaxDrawBuffers; +}; + +TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const +{ + TType gl_FragDataType = TType(EbtFloat, EbpMedium, EvqFragData, 4); + gl_FragDataType.setArraySize(mMaxDrawBuffers); + + TIntermSymbol *symbol = new TIntermSymbol(0, "gl_FragData", gl_FragDataType); + TIntermTyped *indexNode = TIntermTyped::CreateIndexNode(index); + + TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode); + return binary; +} + +TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int index) const +{ + TIntermTyped *fragDataIndex = constructGLFragDataNode(index); + TIntermTyped *fragDataZero = constructGLFragDataNode(0); + + return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero); +} + +void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node) +{ + if (node->getSymbol() == "gl_FragColor") + { + queueReplacement(node, constructGLFragDataNode(0), OriginalNode::IS_DROPPED); + mGLFragColorUsed = true; + } +} + +bool GLFragColorBroadcastTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + switch (node->getOp()) + { + case EOpFunction: + // Function definition. + ASSERT(visit == PreVisit); + if (node->getName() == "main(") + { + TIntermSequence *sequence = node->getSequence(); + ASSERT(sequence->size() == 2); + TIntermAggregate *body = (*sequence)[1]->getAsAggregate(); + ASSERT(body); + mMainSequence = body->getSequence(); + } + break; + default: + break; + } + return true; +} + +void GLFragColorBroadcastTraverser::broadcastGLFragColor() +{ + ASSERT(mMaxDrawBuffers > 1); + if (!mGLFragColorUsed) + { + return; + } + ASSERT(mMainSequence); + // Now insert statements + // gl_FragData[1] = gl_FragData[0]; + // ... + // gl_FragData[maxDrawBuffers - 1] = gl_FragData[0]; + for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex) + { + mMainSequence->insert(mMainSequence->end(), constructGLFragDataAssignNode(colorIndex)); + } +} + +} // namespace anonymous + +void EmulateGLFragColorBroadcast(TIntermNode *root, + int maxDrawBuffers, + std::vector<sh::OutputVariable> *outputVariables) +{ + ASSERT(maxDrawBuffers > 1); + GLFragColorBroadcastTraverser traverser(maxDrawBuffers); + root->traverse(&traverser); + if (traverser.isGLFragColorUsed()) + { + traverser.updateTree(); + traverser.broadcastGLFragColor(); + for (auto &var : *outputVariables) + { + if (var.name == "gl_FragColor") + { + // TODO(zmo): Find a way to keep the original variable information. + var.name = "gl_FragData"; + var.mappedName = "gl_FragData"; + var.arraySize = maxDrawBuffers; + } + } + } +} diff --git a/chromium/third_party/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h b/chromium/third_party/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h new file mode 100644 index 00000000000..627c4c67fe9 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Emulate gl_FragColor broadcast behaviors in ES2 where +// GL_EXT_draw_buffers is explicitly enabled in a fragment shader. +// + +#ifndef COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_ +#define COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_ + +#include <vector> + +namespace sh +{ +struct OutputVariable; +} + +class TIntermNode; + +// Replace all gl_FragColor with gl_FragData[0], and in the end of main() function, +// assign gl_FragData[1] ... gl_FragData[maxDrawBuffers - 1] with gl_FragData[0]. +// If gl_FragColor is in outputVariables, it is replaced by gl_FragData. +void EmulateGLFragColorBroadcast(TIntermNode *root, + int maxDrawBuffers, + std::vector<sh::OutputVariable> *outputVariables); + +#endif // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.cpp b/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.cpp index 4a7fa541558..a3025f07afe 100644 --- a/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.cpp +++ b/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.cpp @@ -6,88 +6,203 @@ #include "compiler/translator/EmulatePrecision.h" +#include <memory> + namespace { -static void writeVectorPrecisionEmulationHelpers( - TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size) +class RoundingHelperWriter : angle::NonCopyable { - std::stringstream vecTypeStrStr; - if (outputLanguage == SH_ESSL_OUTPUT) - vecTypeStrStr << "highp "; - vecTypeStrStr << "vec" << size; - std::string vecType = vecTypeStrStr.str(); - - sink << - vecType << " angle_frm(in " << vecType << " v) {\n" - " v = clamp(v, -65504.0, 65504.0);\n" - " " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n" - " bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n" - " v = v * exp2(-exponent);\n" - " v = sign(v) * floor(abs(v));\n" - " return v * exp2(exponent) * vec" << size << "(isNonZero);\n" - "}\n"; - - sink << - vecType << " angle_frl(in " << vecType << " v) {\n" - " v = clamp(v, -2.0, 2.0);\n" - " v = v * 256.0;\n" - " v = sign(v) * floor(abs(v));\n" - " return v * 0.00390625;\n" - "}\n"; -} + public: + static RoundingHelperWriter *createHelperWriter(const ShShaderOutput outputLanguage); + + void writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion); + void writeCompoundAssignmentHelper(TInfoSinkBase &sink, + const char *lType, + const char *rType, + const char *opStr, + const char *opNameStr); + + virtual ~RoundingHelperWriter() {} + + protected: + RoundingHelperWriter(const ShShaderOutput outputLanguage) : mOutputLanguage(outputLanguage) {} + RoundingHelperWriter() = delete; + + const ShShaderOutput mOutputLanguage; + + private: + virtual std::string getTypeString(const char *glslType) = 0; + virtual void writeFloatRoundingHelpers(TInfoSinkBase &sink) = 0; + virtual void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) = 0; + virtual void writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) = 0; +}; + +class RoundingHelperWriterGLSL : public RoundingHelperWriter +{ + public: + RoundingHelperWriterGLSL(const ShShaderOutput outputLanguage) + : RoundingHelperWriter(outputLanguage) + { + } -static void writeMatrixPrecisionEmulationHelper( - TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size, const char *functionName) + private: + std::string getTypeString(const char *glslType) override; + void writeFloatRoundingHelpers(TInfoSinkBase &sink) override; + void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override; + void writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) override; +}; + +class RoundingHelperWriterESSL : public RoundingHelperWriterGLSL { - std::stringstream matTypeStrStr; - if (outputLanguage == SH_ESSL_OUTPUT) - matTypeStrStr << "highp "; - matTypeStrStr << "mat" << size; - std::string matType = matTypeStrStr.str(); + public: + RoundingHelperWriterESSL(const ShShaderOutput outputLanguage) + : RoundingHelperWriterGLSL(outputLanguage) + { + } - sink << matType << " " << functionName << "(in " << matType << " m) {\n" - " " << matType << " rounded;\n"; + private: + std::string getTypeString(const char *glslType) override; +}; - for (unsigned int i = 0; i < size; ++i) +class RoundingHelperWriterHLSL : public RoundingHelperWriter +{ + public: + RoundingHelperWriterHLSL(const ShShaderOutput outputLanguage) + : RoundingHelperWriter(outputLanguage) { - sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n"; } - sink << " return rounded;\n" - "}\n"; + private: + std::string getTypeString(const char *glslType) override; + void writeFloatRoundingHelpers(TInfoSinkBase &sink) override; + void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override; + void writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) override; +}; + +RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage) +{ + ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage)); + switch (outputLanguage) + { + case SH_HLSL_4_1_OUTPUT: + return new RoundingHelperWriterHLSL(outputLanguage); + case SH_ESSL_OUTPUT: + return new RoundingHelperWriterESSL(outputLanguage); + default: + return new RoundingHelperWriterGLSL(outputLanguage); + } } -static void writeCommonPrecisionEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage) +void RoundingHelperWriter::writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion) { // Write the angle_frm functions that round floating point numbers to // half precision, and angle_frl functions that round them to minimum lowp // precision. + writeFloatRoundingHelpers(sink); + writeVectorRoundingHelpers(sink, 2); + writeVectorRoundingHelpers(sink, 3); + writeVectorRoundingHelpers(sink, 4); + if (shaderVersion > 100) + { + for (unsigned int columns = 2; columns <= 4; ++columns) + { + for (unsigned int rows = 2; rows <= 4; ++rows) + { + writeMatrixRoundingHelper(sink, columns, rows, "angle_frm"); + writeMatrixRoundingHelper(sink, columns, rows, "angle_frl"); + } + } + } + else + { + for (unsigned int size = 2; size <= 4; ++size) + { + writeMatrixRoundingHelper(sink, size, size, "angle_frm"); + writeMatrixRoundingHelper(sink, size, size, "angle_frl"); + } + } +} + +void RoundingHelperWriter::writeCompoundAssignmentHelper(TInfoSinkBase &sink, + const char *lType, + const char *rType, + const char *opStr, + const char *opNameStr) +{ + std::string lTypeStr = getTypeString(lType); + std::string rTypeStr = getTypeString(rType); + + // Note that y should be passed through angle_frm at the function call site, + // but x can't be passed through angle_frm there since it is an inout parameter. + // So only pass x and the result through angle_frm here. + // clang-format off + sink << + lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" + " x = angle_frm(angle_frm(x) " << opStr << " y);\n" + " return x;\n" + "}\n"; + sink << + lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" + " x = angle_frl(angle_frm(x) " << opStr << " y);\n" + " return x;\n" + "}\n"; + // clang-format on +} + +std::string RoundingHelperWriterGLSL::getTypeString(const char *glslType) +{ + return glslType; +} + +std::string RoundingHelperWriterESSL::getTypeString(const char *glslType) +{ + std::stringstream typeStrStr; + typeStrStr << "highp " << glslType; + return typeStrStr.str(); +} + +void RoundingHelperWriterGLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink) +{ // Unoptimized version of angle_frm for single floats: // - // int webgl_maxNormalExponent(in int exponentBits) { + // int webgl_maxNormalExponent(in int exponentBits) + // { // int possibleExponents = int(exp2(float(exponentBits))); // int exponentBias = possibleExponents / 2 - 1; // int allExponentBitsOne = possibleExponents - 1; // return (allExponentBitsOne - 1) - exponentBias; // } // - // float angle_frm(in float x) { + // float angle_frm(in float x) + // { // int mantissaBits = 10; // int exponentBits = 5; // float possibleMantissas = exp2(float(mantissaBits)); // float mantissaMax = 2.0 - 1.0 / possibleMantissas; // int maxNE = webgl_maxNormalExponent(exponentBits); // float max = exp2(float(maxNE)) * mantissaMax; - // if (x > max) { + // if (x > max) + // { // return max; // } - // if (x < -max) { + // if (x < -max) + // { // return -max; // } // float exponent = floor(log2(abs(x))); - // if (abs(x) == 0.0 || exponent < -float(maxNE)) { + // if (abs(x) == 0.0 || exponent < -float(maxNE)) + // { // return 0.0 * sign(x) // } // x = x * exp2(-(exponent - float(mantissaBits))); @@ -109,130 +224,204 @@ static void writeCommonPrecisionEmulationHelpers(TInfoSinkBase& sink, ShShaderOu // numbers will be flushed to zero either way (2^-15 is the smallest // normal positive number), this does not introduce any error. - std::string floatType = "float"; - if (outputLanguage == SH_ESSL_OUTPUT) - floatType = "highp float"; + std::string floatType = getTypeString("float"); + // clang-format off sink << - floatType << " angle_frm(in " << floatType << " x) {\n" - " x = clamp(x, -65504.0, 65504.0);\n" - " " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n" - " bool isNonZero = (exponent >= -25.0);\n" - " x = x * exp2(-exponent);\n" - " x = sign(x) * floor(abs(x));\n" - " return x * exp2(exponent) * float(isNonZero);\n" - "}\n"; + floatType << " angle_frm(in " << floatType << " x) {\n" + " x = clamp(x, -65504.0, 65504.0);\n" + " " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n" + " bool isNonZero = (exponent >= -25.0);\n" + " x = x * exp2(-exponent);\n" + " x = sign(x) * floor(abs(x));\n" + " return x * exp2(exponent) * float(isNonZero);\n" + "}\n"; sink << - floatType << " angle_frl(in " << floatType << " x) {\n" - " x = clamp(x, -2.0, 2.0);\n" - " x = x * 256.0;\n" - " x = sign(x) * floor(abs(x));\n" - " return x * 0.00390625;\n" - "}\n"; - - writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 2); - writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 3); - writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 4); - for (unsigned int size = 2; size <= 4; ++size) + floatType << " angle_frl(in " << floatType << " x) {\n" + " x = clamp(x, -2.0, 2.0);\n" + " x = x * 256.0;\n" + " x = sign(x) * floor(abs(x));\n" + " return x * 0.00390625;\n" + "}\n"; + // clang-format on +} + +void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink, + const unsigned int size) +{ + std::stringstream vecTypeStrStr; + vecTypeStrStr << "vec" << size; + std::string vecType = getTypeString(vecTypeStrStr.str().c_str()); + + // clang-format off + sink << + vecType << " angle_frm(in " << vecType << " v) {\n" + " v = clamp(v, -65504.0, 65504.0);\n" + " " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n" + " bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n" + " v = v * exp2(-exponent);\n" + " v = sign(v) * floor(abs(v));\n" + " return v * exp2(exponent) * vec" << size << "(isNonZero);\n" + "}\n"; + + sink << + vecType << " angle_frl(in " << vecType << " v) {\n" + " v = clamp(v, -2.0, 2.0);\n" + " v = v * 256.0;\n" + " v = sign(v) * floor(abs(v));\n" + " return v * 0.00390625;\n" + "}\n"; + // clang-format on +} + +void RoundingHelperWriterGLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) +{ + std::stringstream matTypeStrStr; + matTypeStrStr << "mat" << columns; + if (rows != columns) { - writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frm"); - writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frl"); + matTypeStrStr << "x" << rows; } + std::string matType = getTypeString(matTypeStrStr.str().c_str()); + + sink << matType << " " << functionName << "(in " << matType << " m) {\n" + << " " << matType << " rounded;\n"; + + for (unsigned int i = 0; i < columns; ++i) + { + sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n"; + } + + sink << " return rounded;\n" + "}\n"; } -static void writeCompoundAssignmentPrecisionEmulation( - TInfoSinkBase& sink, ShShaderOutput outputLanguage, - const char *lType, const char *rType, const char *opStr, const char *opNameStr) +static const char *GetHLSLTypeStr(const char *floatTypeStr) { - std::string lTypeStr = lType; - std::string rTypeStr = rType; - if (outputLanguage == SH_ESSL_OUTPUT) + if (strcmp(floatTypeStr, "float") == 0) { - std::stringstream lTypeStrStr; - lTypeStrStr << "highp " << lType; - lTypeStr = lTypeStrStr.str(); - std::stringstream rTypeStrStr; - rTypeStrStr << "highp " << rType; - rTypeStr = rTypeStrStr.str(); + return "float"; + } + if (strcmp(floatTypeStr, "vec2") == 0) + { + return "float2"; + } + if (strcmp(floatTypeStr, "vec3") == 0) + { + return "float3"; + } + if (strcmp(floatTypeStr, "vec4") == 0) + { + return "float4"; + } + if (strcmp(floatTypeStr, "mat2") == 0) + { + return "float2x2"; + } + if (strcmp(floatTypeStr, "mat3") == 0) + { + return "float3x3"; + } + if (strcmp(floatTypeStr, "mat4") == 0) + { + return "float4x4"; + } + if (strcmp(floatTypeStr, "mat2x3") == 0) + { + return "float2x3"; + } + if (strcmp(floatTypeStr, "mat2x4") == 0) + { + return "float2x4"; + } + if (strcmp(floatTypeStr, "mat3x2") == 0) + { + return "float3x2"; } + if (strcmp(floatTypeStr, "mat3x4") == 0) + { + return "float3x4"; + } + if (strcmp(floatTypeStr, "mat4x2") == 0) + { + return "float4x2"; + } + if (strcmp(floatTypeStr, "mat4x3") == 0) + { + return "float4x3"; + } + UNREACHABLE(); + return nullptr; +} - // Note that y should be passed through angle_frm at the function call site, - // but x can't be passed through angle_frm there since it is an inout parameter. - // So only pass x and the result through angle_frm here. +std::string RoundingHelperWriterHLSL::getTypeString(const char *glslType) +{ + return GetHLSLTypeStr(glslType); +} + +void RoundingHelperWriterHLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink) +{ + // In HLSL scalars are the same as 1-vectors. + writeVectorRoundingHelpers(sink, 1); +} + +void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink, + const unsigned int size) +{ + std::stringstream vecTypeStrStr; + vecTypeStrStr << "float" << size; + std::string vecType = vecTypeStrStr.str(); + + // clang-format off sink << - lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" - " x = angle_frm(angle_frm(x) " << opStr << " y);\n" - " return x;\n" - "}\n"; + vecType << " angle_frm(" << vecType << " v) {\n" + " v = clamp(v, -65504.0, 65504.0);\n" + " " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n" + " bool" << size << " isNonZero = exponent < -25.0;\n" + " v = v * exp2(-exponent);\n" + " v = sign(v) * floor(abs(v));\n" + " return v * exp2(exponent) * (float" << size << ")(isNonZero);\n" + "}\n"; + sink << - lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" - " x = angle_frl(angle_frm(x) " << opStr << " y);\n" - " return x;\n" - "}\n"; + vecType << " angle_frl(" << vecType << " v) {\n" + " v = clamp(v, -2.0, 2.0);\n" + " v = v * 256.0;\n" + " v = sign(v) * floor(abs(v));\n" + " return v * 0.00390625;\n" + "}\n"; + // clang-format on } -const char *getFloatTypeStr(const TType& type) +void RoundingHelperWriterHLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) { - switch (type.getNominalSize()) + std::stringstream matTypeStrStr; + matTypeStrStr << "float" << columns << "x" << rows; + std::string matType = matTypeStrStr.str(); + + sink << matType << " " << functionName << "(" << matType << " m) {\n" + << " " << matType << " rounded;\n"; + + for (unsigned int i = 0; i < columns; ++i) { - case 1: - return "float"; - case 2: - switch(type.getSecondarySize()) - { - case 1: - return "vec2"; - case 2: - return "mat2"; - case 3: - return "mat2x3"; - case 4: - return "mat2x4"; - default: - UNREACHABLE(); - return NULL; - } - case 3: - switch(type.getSecondarySize()) - { - case 1: - return "vec3"; - case 2: - return "mat3x2"; - case 3: - return "mat3"; - case 4: - return "mat3x4"; - default: - UNREACHABLE(); - return NULL; - } - case 4: - switch(type.getSecondarySize()) - { - case 1: - return "vec4"; - case 2: - return "mat4x2"; - case 3: - return "mat4x3"; - case 4: - return "mat4"; - default: - UNREACHABLE(); - return NULL; - } - default: - UNREACHABLE(); - return NULL; + sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n"; } + + sink << " return rounded;\n" + "}\n"; } bool canRoundFloat(const TType &type) { - return type.getBasicType() == EbtFloat && !type.isNonSquareMatrix() && !type.isArray() && - (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium); + return type.getBasicType() == EbtFloat && !type.isArray() && + (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium); } TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child) @@ -253,7 +442,9 @@ TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild) roundFunctionName = "angle_frm"; else roundFunctionName = "angle_frl"; - return createInternalFunctionCallNode(roundFunctionName, roundedChild); + TIntermAggregate *callNode = createInternalFunctionCallNode(roundFunctionName, roundedChild); + callNode->setType(roundedChild->getType()); + return callNode; } TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left, TIntermTyped *right, const char *opNameStr) @@ -302,9 +493,8 @@ void EmulatePrecision::visitSymbol(TIntermSymbol *node) { if (canRoundFloat(node->getType()) && !mDeclaringVariables && !isLValueRequiredHere()) { - TIntermNode *parent = getParentNode(); TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); + queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD); } } @@ -319,7 +509,7 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node) if (op == EOpInitialize && visit == InVisit) mDeclaringVariables = false; - if ((op == EOpIndexDirectStruct || op == EOpVectorSwizzle) && visit == InVisit) + if ((op == EOpIndexDirectStruct) && visit == InVisit) visitChildren = false; if (visit != PreVisit) @@ -350,26 +540,30 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node) break; } TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); + queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD); break; } // Compound assignment cases need to replace the operator with a function call. case EOpAddAssign: { - mEmulateCompoundAdd.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "add"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; + mEmulateCompoundAdd.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "add"); + queueReplacement(node, replacement, OriginalNode::IS_DROPPED); + break; } case EOpSubAssign: { - mEmulateCompoundSub.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "sub"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; + mEmulateCompoundSub.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "sub"); + queueReplacement(node, replacement, OriginalNode::IS_DROPPED); + break; } case EOpMulAssign: case EOpVectorTimesMatrixAssign: @@ -377,19 +571,23 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node) case EOpMatrixTimesScalarAssign: case EOpMatrixTimesMatrixAssign: { - mEmulateCompoundMul.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "mul"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; + mEmulateCompoundMul.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "mul"); + queueReplacement(node, replacement, OriginalNode::IS_DROPPED); + break; } case EOpDivAssign: { - mEmulateCompoundDiv.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "div"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; + mEmulateCompoundDiv.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "div"); + queueReplacement(node, replacement, OriginalNode::IS_DROPPED); + break; } default: // The rest of the binary operations should not need precision emulation. @@ -444,7 +642,7 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node) parentUsesResult(parent, node)) { TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); + queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD); } } break; @@ -454,7 +652,7 @@ bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node) if (canRoundFloat(node->getType()) && visit == PreVisit && parentUsesResult(parent, node)) { TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); + queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD); } break; } @@ -476,9 +674,8 @@ bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node) default: if (canRoundFloat(node->getType()) && visit == PreVisit) { - TIntermNode *parent = getParentNode(); TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); + queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD); } break; } @@ -486,22 +683,37 @@ bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node) return true; } -void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage) +void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink, + const int shaderVersion, + const ShShaderOutput outputLanguage) { - // Other languages not yet supported - ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT || - IsGLSL130OrNewer(outputLanguage) || - outputLanguage == SH_ESSL_OUTPUT); - writeCommonPrecisionEmulationHelpers(sink, outputLanguage); + std::unique_ptr<RoundingHelperWriter> roundingHelperWriter( + RoundingHelperWriter::createHelperWriter(outputLanguage)); + + roundingHelperWriter->writeCommonRoundingHelpers(sink, shaderVersion); EmulationSet::const_iterator it; for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "+", "add"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "+", "add"); for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "-", "sub"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "-", "sub"); for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "/", "div"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "/", "div"); for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "*", "mul"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul"); } +// static +bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage) +{ + switch (outputLanguage) + { + case SH_HLSL_4_1_OUTPUT: + case SH_ESSL_OUTPUT: + return true; + default: + // Other languages not yet supported + return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT || + IsGLSL130OrNewer(outputLanguage)); + } +} diff --git a/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.h b/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.h index 08177b3414f..f23e40be7f5 100644 --- a/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.h +++ b/chromium/third_party/angle/src/compiler/translator/EmulatePrecision.h @@ -28,7 +28,11 @@ class EmulatePrecision : public TLValueTrackingTraverser bool visitUnary(Visit visit, TIntermUnary *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override; - void writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage); + void writeEmulationHelpers(TInfoSinkBase &sink, + const int shaderVersion, + const ShShaderOutput outputLanguage); + + static bool SupportedInLanguage(const ShShaderOutput outputLanguage); private: struct TypePair diff --git a/chromium/third_party/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp b/chromium/third_party/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp new file mode 100644 index 00000000000..9409c010f14 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp @@ -0,0 +1,154 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of the integer pow expressions HLSL bug workaround. +// See header for more info. + +#include "compiler/translator/ExpandIntegerPowExpressions.h" + +#include <cmath> +#include <cstdlib> + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +namespace +{ + +class Traverser : public TIntermTraverser +{ + public: + static void Apply(TIntermNode *root, unsigned int *tempIndex); + + private: + Traverser(); + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + void nextIteration(); + + bool mFound = false; +}; + +// static +void Traverser::Apply(TIntermNode *root, unsigned int *tempIndex) +{ + Traverser traverser; + traverser.useTemporaryIndex(tempIndex); + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.mFound) + { + traverser.updateTree(); + } + } while (traverser.mFound); +} + +Traverser::Traverser() : TIntermTraverser(true, false, false) +{ +} + +void Traverser::nextIteration() +{ + mFound = false; + nextTemporaryIndex(); +} + +bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mFound) + { + return false; + } + + // Test 0: skip non-pow operators. + if (node->getOp() != EOpPow) + { + return true; + } + + const TIntermSequence *sequence = node->getSequence(); + ASSERT(sequence->size() == 2u); + const TIntermConstantUnion *constantNode = sequence->at(1)->getAsConstantUnion(); + + // Test 1: check for a single constant. + if (!constantNode || constantNode->getNominalSize() != 1) + { + return true; + } + + const TConstantUnion *constant = constantNode->getUnionArrayPointer(); + + TConstantUnion asFloat; + asFloat.cast(EbtFloat, *constant); + + float value = asFloat.getFConst(); + + // Test 2: value is in the problematic range. + if (value < -5.0f || value > 9.0f) + { + return true; + } + + // Test 3: value is integer or pretty close to an integer. + float absval = std::abs(value); + float frac = absval - std::round(absval); + if (frac > 0.0001f) + { + return true; + } + + // Test 4: skip -1, 0, and 1 + int exponent = static_cast<int>(value); + int n = std::abs(exponent); + if (n < 2) + { + return true; + } + + // Potential problem case detected, apply workaround. + nextTemporaryIndex(); + + TIntermTyped *lhs = sequence->at(0)->getAsTyped(); + ASSERT(lhs); + + TIntermAggregate *init = createTempInitDeclaration(lhs); + TIntermTyped *current = createTempSymbol(lhs->getType()); + + insertStatementInParentBlock(init); + + // Create a chain of n-1 multiples. + for (int i = 1; i < n; ++i) + { + TIntermBinary *mul = new TIntermBinary(EOpMul, current, createTempSymbol(lhs->getType())); + mul->setLine(node->getLine()); + current = mul; + } + + // For negative pow, compute the reciprocal of the positive pow. + if (exponent < 0) + { + TConstantUnion *oneVal = new TConstantUnion(); + oneVal->setFConst(1.0f); + TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType()); + TIntermBinary *div = new TIntermBinary(EOpDiv, oneNode, current); + current = div; + } + + queueReplacement(node, current, OriginalNode::IS_DROPPED); + mFound = true; + return false; +} + +} // anonymous namespace + +void ExpandIntegerPowExpressions(TIntermNode *root, unsigned int *tempIndex) +{ + Traverser::Apply(root, tempIndex); +} + +} // namespace sh diff --git a/chromium/third_party/angle/src/compiler/translator/ExpandIntegerPowExpressions.h b/chromium/third_party/angle/src/compiler/translator/ExpandIntegerPowExpressions.h new file mode 100644 index 00000000000..8bc8c9664ed --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/ExpandIntegerPowExpressions.h @@ -0,0 +1,28 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This mutating tree traversal works around a bug in the HLSL compiler optimizer with "pow" that +// manifests under the following conditions: +// +// - If pow() has a literal exponent value +// - ... and this value is integer or within 10e-6 of an integer +// - ... and it is in {-4, -3, -2, 2, 3, 4, 5, 6, 7, 8} +// +// The workaround is to replace the pow with a series of multiplies. +// See http://anglebug.com/851 + +#ifndef COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_ +#define COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_ + +class TIntermNode; + +namespace sh +{ + +void ExpandIntegerPowExpressions(TIntermNode *root, unsigned int *tempIndex); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/Initialize.cpp b/chromium/third_party/angle/src/compiler/translator/Initialize.cpp index b45e47ba992..759834f8575 100644 --- a/chromium/third_party/angle/src/compiler/translator/Initialize.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Initialize.cpp @@ -495,30 +495,85 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR // // Implementation dependent built-in constants. // - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", resources.MaxTextureImageUnits); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors); - - symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors); - - if (spec != SH_CSS_SHADERS_SPEC) + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs, + EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", + resources.MaxVertexUniformVectors, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", + resources.MaxVertexTextureImageUnits, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", + resources.MaxCombinedTextureImageUnits, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", + resources.MaxTextureImageUnits, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", + resources.MaxFragmentUniformVectors, EbpMedium); + + symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors, + EbpMedium); + + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers, + EbpMedium); + if (resources.EXT_blend_func_extended) { - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers); - if (resources.EXT_blend_func_extended) - { - symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended", - "gl_MaxDualSourceDrawBuffersEXT", - resources.MaxDualSourceDrawBuffers); - } + symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended", + "gl_MaxDualSourceDrawBuffersEXT", + resources.MaxDualSourceDrawBuffers); } - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors); - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", resources.MaxFragmentInputVectors); - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", resources.MinProgramTexelOffset); - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", resources.MaxProgramTexelOffset); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", + resources.MaxVertexOutputVectors, EbpMedium); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", + resources.MaxFragmentInputVectors, EbpMedium); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", + resources.MinProgramTexelOffset, EbpMedium); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", + resources.MaxProgramTexelOffset, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxImageUnits", resources.MaxImageUnits, + EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms", + resources.MaxVertexImageUniforms, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms", + resources.MaxFragmentImageUniforms, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms", + resources.MaxComputeImageUniforms, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms", + resources.MaxCombinedImageUniforms, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources", + resources.MaxCombinedShaderOutputResources, EbpMedium); + + symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount", + resources.MaxComputeWorkGroupCount, EbpHigh); + symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize", + resources.MaxComputeWorkGroupSize, EbpHigh); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents", + resources.MaxComputeUniformComponents, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits", + resources.MaxComputeTextureImageUnits, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters", + resources.MaxComputeAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers", + resources.MaxComputeAtomicCounterBuffers, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters", + resources.MaxVertexAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters", + resources.MaxFragmentAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters", + resources.MaxCombinedAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings", + resources.MaxAtomicCounterBindings, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers", + resources.MaxVertexAtomicCounterBuffers, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers", + resources.MaxFragmentAtomicCounterBuffers, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers", + resources.MaxCombinedAtomicCounterBuffers, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize", + resources.MaxAtomicCounterBufferSize, EbpMedium); } void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, @@ -532,85 +587,73 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, switch (type) { case GL_FRAGMENT_SHADER: - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), - TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), - TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), - TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); - - // - // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available. - // Instead, css_MixColor and css_ColorMatrix are available. - // - if (spec != SH_CSS_SHADERS_SPEC) - { - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), - TType(EbtFloat, EbpMedium, EvqFragColor, 4))); - TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true); - fragData.setArraySize(resources.MaxDrawBuffers); - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData)); - - if (resources.EXT_blend_func_extended) - { - symbolTable.insert( - ESSL1_BUILTINS, "GL_EXT_blend_func_extended", - new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"), - TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4))); - TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true); - secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers); - symbolTable.insert( - ESSL1_BUILTINS, "GL_EXT_blend_func_extended", - new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData)); - } - - if (resources.EXT_frag_depth) - { - symbolTable.insert( - ESSL1_BUILTINS, "GL_EXT_frag_depth", - new TVariable( - NewPoolTString("gl_FragDepthEXT"), - TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, - EvqFragDepthEXT, 1))); - } - - symbolTable.insert(ESSL3_BUILTINS, - new TVariable(NewPoolTString("gl_FragDepth"), - TType(EbtFloat, EbpHigh, EvqFragDepth, 1))); - - if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch) - { - TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true); - lastFragData.setArraySize(resources.MaxDrawBuffers); - - if (resources.EXT_shader_framebuffer_fetch) - { - symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragData"), lastFragData)); - } - else if (resources.NV_shader_framebuffer_fetch) - { - symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragColor"), - TType(EbtFloat, EbpMedium, EvqLastFragColor, 4))); - symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragData"), lastFragData)); - } - } - else if (resources.ARM_shader_framebuffer_fetch) - { - symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragColorARM"), - TType(EbtFloat, EbpMedium, EvqLastFragColor, 4))); - } - } - else - { - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"), - TType(EbtFloat, EbpMedium, EvqGlobal, 4))); - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"), - TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4))); - } + { + symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), + TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); + symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), + TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); + symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), + TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); + + symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), + TType(EbtFloat, EbpMedium, EvqFragColor, 4))); + TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true); + fragData.setArraySize(resources.MaxDrawBuffers); + symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData)); + + if (resources.EXT_blend_func_extended) + { + symbolTable.insert( + ESSL1_BUILTINS, "GL_EXT_blend_func_extended", + new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"), + TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4))); + TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true); + secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers); + symbolTable.insert( + ESSL1_BUILTINS, "GL_EXT_blend_func_extended", + new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData)); + } + + if (resources.EXT_frag_depth) + { + symbolTable.insert( + ESSL1_BUILTINS, "GL_EXT_frag_depth", + new TVariable( + NewPoolTString("gl_FragDepthEXT"), + TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, + EvqFragDepthEXT, 1))); + } + + symbolTable.insert(ESSL3_BUILTINS, + new TVariable(NewPoolTString("gl_FragDepth"), + TType(EbtFloat, EbpHigh, EvqFragDepth, 1))); + + if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch) + { + TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true); + lastFragData.setArraySize(resources.MaxDrawBuffers); + + if (resources.EXT_shader_framebuffer_fetch) + { + symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch", + new TVariable(NewPoolTString("gl_LastFragData"), lastFragData)); + } + else if (resources.NV_shader_framebuffer_fetch) + { + symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch", + new TVariable(NewPoolTString("gl_LastFragColor"), + TType(EbtFloat, EbpMedium, EvqLastFragColor, 4))); + symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch", + new TVariable(NewPoolTString("gl_LastFragData"), lastFragData)); + } + } + else if (resources.ARM_shader_framebuffer_fetch) + { + symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch", + new TVariable(NewPoolTString("gl_LastFragColorARM"), + TType(EbtFloat, EbpMedium, EvqLastFragColor, 4))); + } + } break; @@ -624,6 +667,29 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1))); break; + case GL_COMPUTE_SHADER: + { + symbolTable.insert(ESSL3_1_BUILTINS, + new TVariable(NewPoolTString("gl_NumWorkGroups"), + TType(EbtUInt, EbpUndefined, EvqNumWorkGroups, 3))); + symbolTable.insert(ESSL3_1_BUILTINS, + new TVariable(NewPoolTString("gl_WorkGroupSize"), + TType(EbtUInt, EbpUndefined, EvqWorkGroupSize, 3))); + symbolTable.insert(ESSL3_1_BUILTINS, + new TVariable(NewPoolTString("gl_WorkGroupID"), + TType(EbtUInt, EbpUndefined, EvqWorkGroupID, 3))); + symbolTable.insert(ESSL3_1_BUILTINS, + new TVariable(NewPoolTString("gl_LocalInvocationID"), + TType(EbtUInt, EbpUndefined, EvqLocalInvocationID, 3))); + symbolTable.insert(ESSL3_1_BUILTINS, + new TVariable(NewPoolTString("gl_GlobalInvocationID"), + TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3))); + symbolTable.insert( + ESSL3_1_BUILTINS, + new TVariable(NewPoolTString("gl_LocalInvocationIndex"), + TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1))); + } + break; default: assert(false && "Language not supported"); diff --git a/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp index 86d3e6bc839..235f49893c4 100644 --- a/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp +++ b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.cpp @@ -6,40 +6,41 @@ #include "compiler/translator/InitializeVariables.h" +#include "angle_gl.h" #include "common/debug.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/util.h" namespace { -TIntermConstantUnion *constructFloatConstUnionNode(const TType &type) +class VariableInitializer : public TIntermTraverser { - TType myType = type; - unsigned char size = static_cast<unsigned char>(myType.getNominalSize()); - if (myType.isMatrix()) - size *= size; - TConstantUnion *u = new TConstantUnion[size]; - for (int ii = 0; ii < size; ++ii) - u[ii].setFConst(0.0f); - - myType.clearArrayness(); - myType.setQualifier(EvqConst); - TIntermConstantUnion *node = new TIntermConstantUnion(u, myType); - return node; -} + public: + VariableInitializer(const InitVariableList &vars) + : TIntermTraverser(true, false, false), mVariables(vars), mCodeInserted(false) + { + } -TIntermConstantUnion *constructIndexNode(int index) -{ - TConstantUnion *u = new TConstantUnion[1]; - u[0].setIConst(index); + protected: + bool visitBinary(Visit, TIntermBinary *node) override { return false; } + bool visitUnary(Visit, TIntermUnary *node) override { return false; } + bool visitIfElse(Visit, TIntermIfElse *node) override { return false; } + bool visitLoop(Visit, TIntermLoop *node) override { return false; } + bool visitBranch(Visit, TIntermBranch *node) override { return false; } - TType type(EbtInt, EbpUndefined, EvqConst, 1); - TIntermConstantUnion *node = new TIntermConstantUnion(u, type); - return node; -} + bool visitAggregate(Visit visit, TIntermAggregate *node) override; -} // namespace anonymous + private: + void insertInitCode(TIntermSequence *sequence); + + const InitVariableList &mVariables; + bool mCodeInserted; +}; + +// VariableInitializer implementation. -bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node) +bool VariableInitializer::visitAggregate(Visit visit, TIntermAggregate *node) { bool visitChildren = !mCodeInserted; switch (node->getOp()) @@ -53,17 +54,8 @@ bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node) if (node->getName() == "main(") { TIntermSequence *sequence = node->getSequence(); - ASSERT((sequence->size() == 1) || (sequence->size() == 2)); - TIntermAggregate *body = NULL; - if (sequence->size() == 1) - { - body = new TIntermAggregate(EOpSequence); - sequence->push_back(body); - } - else - { - body = (*sequence)[1]->getAsAggregate(); - } + ASSERT(sequence->size() == 2); + TIntermAggregate *body = (*sequence)[1]->getAsAggregate(); ASSERT(body); insertInitCode(body->getSequence()); mCodeInserted = true; @@ -77,41 +69,52 @@ bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node) return visitChildren; } -void InitializeVariables::insertInitCode(TIntermSequence *sequence) +void VariableInitializer::insertInitCode(TIntermSequence *sequence) { - for (size_t ii = 0; ii < mVariables.size(); ++ii) + for (const auto &var : mVariables) { - const InitVariableInfo &varInfo = mVariables[ii]; + TString name = TString(var.name.c_str()); + TType type = sh::GetShaderVariableType(var); - if (varInfo.type.isArray()) + // Assign the array elements one by one to keep the AST compatible with ESSL 1.00 which + // doesn't have array assignment. + if (var.isArray()) { - for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index) + size_t pos = name.find_last_of('['); + if (pos != TString::npos) { - TIntermBinary *assign = new TIntermBinary(EOpAssign); - sequence->insert(sequence->begin(), assign); + name = name.substr(0, pos); + } + TType elementType = type; + elementType.clearArrayness(); - TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect); - TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); - indexDirect->setLeft(symbol); - TIntermConstantUnion *indexNode = constructIndexNode(index); - indexDirect->setRight(indexNode); + for (unsigned int i = 0; i < var.arraySize; ++i) + { + TIntermSymbol *arraySymbol = new TIntermSymbol(0, name, type); + TIntermBinary *element = new TIntermBinary(EOpIndexDirect, arraySymbol, + TIntermTyped::CreateIndexNode(i)); - assign->setLeft(indexDirect); + TIntermTyped *zero = TIntermTyped::CreateZero(elementType); + TIntermBinary *assignment = new TIntermBinary(EOpAssign, element, zero); - TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); - assign->setRight(zeroConst); + sequence->insert(sequence->begin(), assignment); } } else { - TIntermBinary *assign = new TIntermBinary(EOpAssign); + TIntermSymbol *symbol = new TIntermSymbol(0, name, type); + TIntermTyped *zero = TIntermTyped::CreateZero(type); + + TIntermBinary *assign = new TIntermBinary(EOpAssign, symbol, zero); sequence->insert(sequence->begin(), assign); - TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); - assign->setLeft(symbol); - TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); - assign->setRight(zeroConst); } - } } +} // namespace anonymous + +void InitializeVariables(TIntermNode *root, const InitVariableList &vars) +{ + VariableInitializer initializer(vars); + root->traverse(&initializer); +} diff --git a/chromium/third_party/angle/src/compiler/translator/InitializeVariables.h b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.h index 2a141ec91cf..dce1083f66b 100644 --- a/chromium/third_party/angle/src/compiler/translator/InitializeVariables.h +++ b/chromium/third_party/angle/src/compiler/translator/InitializeVariables.h @@ -7,45 +7,13 @@ #ifndef COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ #define COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ -#include "compiler/translator/IntermNode.h" +#include <GLSLANG/ShaderLang.h> -class InitializeVariables : public TIntermTraverser -{ - public: - struct InitVariableInfo - { - TString name; - TType type; +class TIntermNode; - InitVariableInfo(const TString &_name, const TType &_type) - : name(_name), - type(_type) - { - } - }; - typedef TVector<InitVariableInfo> InitVariableInfoList; +typedef std::vector<sh::ShaderVariable> InitVariableList; - InitializeVariables(const InitVariableInfoList &vars) - : TIntermTraverser(true, false, false), - mVariables(vars), - mCodeInserted(false) - { - } - - protected: - bool visitBinary(Visit, TIntermBinary *node) override { return false; } - bool visitUnary(Visit, TIntermUnary *node) override { return false; } - bool visitSelection(Visit, TIntermSelection *node) override { return false; } - bool visitLoop(Visit, TIntermLoop *node) override { return false; } - bool visitBranch(Visit, TIntermBranch *node) override { return false; } - - bool visitAggregate(Visit visit, TIntermAggregate *node) override; - - private: - void insertInitCode(TIntermSequence *sequence); - - InitVariableInfoList mVariables; - bool mCodeInserted; -}; +// This function cannot currently initialize structures containing arrays for an ESSL 1.00 backend. +void InitializeVariables(TIntermNode *root, const InitVariableList &vars); #endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/IntermNode.cpp b/chromium/third_party/angle/src/compiler/translator/IntermNode.cpp index ccbd80f4766..09bc972a976 100644 --- a/chromium/third_party/angle/src/compiler/translator/IntermNode.cpp +++ b/chromium/third_party/angle/src/compiler/translator/IntermNode.cpp @@ -17,9 +17,11 @@ #include "common/mathutil.h" #include "common/matrix_utils.h" +#include "compiler/translator/Diagnostics.h" #include "compiler/translator/HashNames.h" #include "compiler/translator/IntermNode.h" #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/util.h" namespace { @@ -33,41 +35,6 @@ TPrecision GetHigherPrecision(TPrecision left, TPrecision right) return left > right ? left : right; } -bool ValidateMultiplication(TOperator op, const TType &left, const TType &right) -{ - switch (op) - { - case EOpMul: - case EOpMulAssign: - return left.getNominalSize() == right.getNominalSize() && - left.getSecondarySize() == right.getSecondarySize(); - case EOpVectorTimesScalar: - case EOpVectorTimesScalarAssign: - return true; - case EOpVectorTimesMatrix: - return left.getNominalSize() == right.getRows(); - case EOpVectorTimesMatrixAssign: - return left.getNominalSize() == right.getRows() && - left.getNominalSize() == right.getCols(); - case EOpMatrixTimesVector: - return left.getCols() == right.getNominalSize(); - case EOpMatrixTimesScalar: - case EOpMatrixTimesScalarAssign: - return true; - case EOpMatrixTimesMatrix: - return left.getCols() == right.getRows(); - case EOpMatrixTimesMatrixAssign: - // We need to check two things: - // 1. The matrix multiplication step is valid. - // 2. The result will have the same number of columns as the lvalue. - return left.getCols() == right.getRows() && left.getCols() == right.getCols(); - - default: - UNREACHABLE(); - return false; - } -} - TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size) { TConstantUnion *constUnion = new TConstantUnion[size]; @@ -77,13 +44,14 @@ TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size) return constUnion; } -void UndefinedConstantFoldingError(const TSourceLoc &loc, TOperator op, TBasicType basicType, - TInfoSink &infoSink, TConstantUnion *result) +void UndefinedConstantFoldingError(const TSourceLoc &loc, + TOperator op, + TBasicType basicType, + TDiagnostics *diagnostics, + TConstantUnion *result) { - std::stringstream constantFoldingErrorStream; - constantFoldingErrorStream << "'" << GetOperatorString(op) - << "' operation result is undefined for the values passed in"; - infoSink.info.message(EPrefixWarning, loc, constantFoldingErrorStream.str().c_str()); + diagnostics->warning(loc, "operation result is undefined for the values passed in", + GetOperatorString(op), ""); switch (basicType) { @@ -125,7 +93,7 @@ float VectorDotProduct(const TConstantUnion *paramArray1, return result; } -TIntermTyped *CreateFoldedNode(TConstantUnion *constArray, +TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTyped *originalNode, TQualifier qualifier) { @@ -147,8 +115,9 @@ angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, for (size_t i = 0; i < rows * cols; i++) elements.push_back(paramArray[i].getFConst()); // Transpose is used since the Matrix constructor expects arguments in row-major order, - // whereas the paramArray is in column-major order. - return angle::Matrix<float>(elements, rows, cols).transpose(); + // whereas the paramArray is in column-major order. Rows/cols parameters are also flipped below + // so that the created matrix will have the expected dimensions after the transpose. + return angle::Matrix<float>(elements, cols, rows).transpose(); } angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, const unsigned int &size) @@ -197,6 +166,7 @@ void TIntermTyped::setTypePreservePrecision(const TType &t) bool TIntermLoop::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { + ASSERT(original != nullptr); // This risks replacing multiple children. REPLACE_IF_IS(mInit, TIntermNode, original, replacement); REPLACE_IF_IS(mCond, TIntermTyped, original, replacement); REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement); @@ -211,6 +181,13 @@ bool TIntermBranch::replaceChildNode( return false; } +bool TIntermSwizzle::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType()); + REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement); + return false; +} + bool TIntermBinary::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { @@ -222,6 +199,7 @@ bool TIntermBinary::replaceChildNode( bool TIntermUnary::replaceChildNode( TIntermNode *original, TIntermNode *replacement) { + ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType()); REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement); return false; } @@ -321,12 +299,19 @@ void TIntermAggregate::setBuiltInFunctionPrecision() mType.setPrecision(precision); } -bool TIntermSelection::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement); - REPLACE_IF_IS(mTrueBlock, TIntermNode, original, replacement); - REPLACE_IF_IS(mFalseBlock, TIntermNode, original, replacement); + REPLACE_IF_IS(mTrueExpression, TIntermTyped, original, replacement); + REPLACE_IF_IS(mFalseExpression, TIntermTyped, original, replacement); + return false; +} + +bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement); + REPLACE_IF_IS(mTrueBlock, TIntermAggregate, original, replacement); + REPLACE_IF_IS(mFalseBlock, TIntermAggregate, original, replacement); return false; } @@ -368,6 +353,83 @@ bool TIntermTyped::isConstructorWithOnlyConstantUnionParameters() return true; } +// static +TIntermTyped *TIntermTyped::CreateIndexNode(int index) +{ + TConstantUnion *u = new TConstantUnion[1]; + u[0].setIConst(index); + + TType type(EbtInt, EbpUndefined, EvqConst, 1); + TIntermConstantUnion *node = new TIntermConstantUnion(u, type); + return node; +} + +// static +TIntermTyped *TIntermTyped::CreateZero(const TType &type) +{ + TType constType(type); + constType.setQualifier(EvqConst); + + if (!type.isArray() && type.getBasicType() != EbtStruct) + { + ASSERT(type.isScalar() || type.isVector() || type.isMatrix()); + + size_t size = constType.getObjectSize(); + TConstantUnion *u = new TConstantUnion[size]; + for (size_t i = 0; i < size; ++i) + { + switch (type.getBasicType()) + { + case EbtFloat: + u[i].setFConst(0.0f); + break; + case EbtInt: + u[i].setIConst(0); + break; + case EbtUInt: + u[i].setUConst(0u); + break; + case EbtBool: + u[i].setBConst(false); + break; + default: + UNREACHABLE(); + return nullptr; + } + } + + TIntermConstantUnion *node = new TIntermConstantUnion(u, constType); + return node; + } + + TIntermAggregate *constructor = new TIntermAggregate(sh::TypeToConstructorOperator(type)); + constructor->setType(constType); + + if (type.isArray()) + { + TType elementType(type); + elementType.clearArrayness(); + + size_t arraySize = type.getArraySize(); + for (size_t i = 0; i < arraySize; ++i) + { + constructor->getSequence()->push_back(CreateZero(elementType)); + } + } + else + { + ASSERT(type.getBasicType() == EbtStruct); + + TStructure *structure = type.getStruct(); + for (const auto &field : structure->fields()) + { + constructor->getSequence()->push_back(CreateZero(*field->type())); + } + } + + return constructor; +} + TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node) { mUnionArrayPointer = node.mUnionArrayPointer; @@ -390,6 +452,13 @@ TIntermAggregate::TIntermAggregate(const TIntermAggregate &node) } } +TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermTyped(node) +{ + TIntermTyped *operandCopy = node.mOperand->deepCopy(); + ASSERT(operandCopy != nullptr); + mOperand = operandCopy; +} + TIntermBinary::TIntermBinary(const TIntermBinary &node) : TIntermOperator(node), mAddIndexClamp(node.mAddIndexClamp) { @@ -408,52 +477,20 @@ TIntermUnary::TIntermUnary(const TIntermUnary &node) mOperand = operandCopy; } -TIntermSelection::TIntermSelection(const TIntermSelection &node) : TIntermTyped(node) +TIntermTernary::TIntermTernary(const TIntermTernary &node) : TIntermTyped(node) { - // Only supported for ternary nodes, not if statements. - TIntermTyped *trueTyped = node.mTrueBlock->getAsTyped(); - TIntermTyped *falseTyped = node.mFalseBlock->getAsTyped(); - ASSERT(trueTyped != nullptr); - ASSERT(falseTyped != nullptr); TIntermTyped *conditionCopy = node.mCondition->deepCopy(); - TIntermTyped *trueCopy = trueTyped->deepCopy(); - TIntermTyped *falseCopy = falseTyped->deepCopy(); + TIntermTyped *trueCopy = node.mTrueExpression->deepCopy(); + TIntermTyped *falseCopy = node.mFalseExpression->deepCopy(); ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr); - mCondition = conditionCopy; - mTrueBlock = trueCopy; - mFalseBlock = falseCopy; + mCondition = conditionCopy; + mTrueExpression = trueCopy; + mFalseExpression = falseCopy; } -// -// Say whether or not an operation node changes the value of a variable. -// bool TIntermOperator::isAssignment() const { - switch (mOp) - { - case EOpPostIncrement: - case EOpPostDecrement: - case EOpPreIncrement: - case EOpPreDecrement: - case EOpAssign: - case EOpAddAssign: - case EOpSubAssign: - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: - case EOpDivAssign: - case EOpIModAssign: - case EOpBitShiftLeftAssign: - case EOpBitShiftRightAssign: - case EOpBitwiseAndAssign: - case EOpBitwiseXorAssign: - case EOpBitwiseOrAssign: - return true; - default: - return false; - } + return IsAssignment(mOp); } bool TIntermOperator::isMultiplication() const @@ -511,74 +548,260 @@ bool TIntermOperator::isConstructor() const } } +TOperator TIntermBinary::GetMulOpBasedOnOperands(const TType &left, const TType &right) +{ + if (left.isMatrix()) + { + if (right.isMatrix()) + { + return EOpMatrixTimesMatrix; + } + else + { + if (right.isVector()) + { + return EOpMatrixTimesVector; + } + else + { + return EOpMatrixTimesScalar; + } + } + } + else + { + if (right.isMatrix()) + { + if (left.isVector()) + { + return EOpVectorTimesMatrix; + } + else + { + return EOpMatrixTimesScalar; + } + } + else + { + // Neither operand is a matrix. + if (left.isVector() == right.isVector()) + { + // Leave as component product. + return EOpMul; + } + else + { + return EOpVectorTimesScalar; + } + } + } +} + +TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const TType &right) +{ + if (left.isMatrix()) + { + if (right.isMatrix()) + { + return EOpMatrixTimesMatrixAssign; + } + else + { + // right should be scalar, but this may not be validated yet. + return EOpMatrixTimesScalarAssign; + } + } + else + { + if (right.isMatrix()) + { + // Left should be a vector, but this may not be validated yet. + return EOpVectorTimesMatrixAssign; + } + else + { + // Neither operand is a matrix. + if (left.isVector() == right.isVector()) + { + // Leave as component product. + return EOpMulAssign; + } + else + { + // left should be vector and right should be scalar, but this may not be validated + // yet. + return EOpVectorTimesScalarAssign; + } + } + } +} + // // Make sure the type of a unary operator is appropriate for its // combination of operation and operand type. // -void TIntermUnary::promote(const TType *funcReturnType) +void TIntermUnary::promote() { + TQualifier resultQualifier = EvqTemporary; + if (mOperand->getQualifier() == EvqConst) + resultQualifier = EvqConst; + + unsigned char operandPrimarySize = + static_cast<unsigned char>(mOperand->getType().getNominalSize()); switch (mOp) { - case EOpFloatBitsToInt: - case EOpFloatBitsToUint: - case EOpIntBitsToFloat: - case EOpUintBitsToFloat: - case EOpPackSnorm2x16: - case EOpPackUnorm2x16: - case EOpPackHalf2x16: - case EOpUnpackSnorm2x16: - case EOpUnpackUnorm2x16: - mType.setPrecision(EbpHigh); - break; - case EOpUnpackHalf2x16: - mType.setPrecision(EbpMedium); - break; - default: - setType(mOperand->getType()); + case EOpFloatBitsToInt: + setType(TType(EbtInt, EbpHigh, resultQualifier, operandPrimarySize)); + break; + case EOpFloatBitsToUint: + setType(TType(EbtUInt, EbpHigh, resultQualifier, operandPrimarySize)); + break; + case EOpIntBitsToFloat: + case EOpUintBitsToFloat: + setType(TType(EbtFloat, EbpHigh, resultQualifier, operandPrimarySize)); + break; + case EOpPackSnorm2x16: + case EOpPackUnorm2x16: + case EOpPackHalf2x16: + setType(TType(EbtUInt, EbpHigh, resultQualifier)); + break; + case EOpUnpackSnorm2x16: + case EOpUnpackUnorm2x16: + setType(TType(EbtFloat, EbpHigh, resultQualifier, 2)); + break; + case EOpUnpackHalf2x16: + setType(TType(EbtFloat, EbpMedium, resultQualifier, 2)); + break; + case EOpAny: + case EOpAll: + setType(TType(EbtBool, EbpUndefined, resultQualifier)); + break; + case EOpLength: + case EOpDeterminant: + setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier)); + break; + case EOpTranspose: + setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier, + static_cast<unsigned char>(mOperand->getType().getRows()), + static_cast<unsigned char>(mOperand->getType().getCols()))); + break; + case EOpIsInf: + case EOpIsNan: + setType(TType(EbtBool, EbpUndefined, resultQualifier, operandPrimarySize)); + break; + default: + setType(mOperand->getType()); + mType.setQualifier(resultQualifier); + break; + } +} + +TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets) + : TIntermTyped(TType(EbtFloat, EbpUndefined)), + mOperand(operand), + mSwizzleOffsets(swizzleOffsets) +{ + ASSERT(mSwizzleOffsets.size() <= 4); + promote(); +} + +TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand) + : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false) +{ + promote(); +} + +TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right) + : TIntermOperator(op), mLeft(left), mRight(right), mAddIndexClamp(false) +{ + promote(); +} + +TIntermTernary::TIntermTernary(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression) + : TIntermTyped(trueExpression->getType()), + mCondition(cond), + mTrueExpression(trueExpression), + mFalseExpression(falseExpression) +{ + getTypePointer()->setQualifier( + TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression)); +} + +// static +TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression) +{ + if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst && + falseExpression->getQualifier() == EvqConst) + { + return EvqConst; } + return EvqTemporary; +} + +void TIntermSwizzle::promote() +{ + TQualifier resultQualifier = EvqTemporary; + if (mOperand->getQualifier() == EvqConst) + resultQualifier = EvqConst; - if (funcReturnType != nullptr) + auto numFields = mSwizzleOffsets.size(); + setType(TType(mOperand->getBasicType(), mOperand->getPrecision(), resultQualifier, + static_cast<unsigned char>(numFields))); +} + +bool TIntermSwizzle::hasDuplicateOffsets() const +{ + int offsetCount[4] = {0u, 0u, 0u, 0u}; + for (const auto offset : mSwizzleOffsets) { - if (funcReturnType->getBasicType() == EbtBool) + offsetCount[offset]++; + if (offsetCount[offset] > 1) { - // Bool types should not have precision. - setType(*funcReturnType); + return true; } - else + } + return false; +} + +void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const +{ + for (const int offset : mSwizzleOffsets) + { + switch (offset) { - // Precision of the node has been set based on the operand. - setTypePreservePrecision(*funcReturnType); + case 0: + *out << "x"; + break; + case 1: + *out << "y"; + break; + case 2: + *out << "z"; + break; + case 3: + *out << "w"; + break; + default: + UNREACHABLE(); } } - - if (mOperand->getQualifier() == EvqConst) - mType.setQualifier(EvqConst); - else - mType.setQualifier(EvqTemporary); } -// -// Establishes the type of the resultant operation, as well as -// makes the operator the correct one for the operands. -// -// For lots of operations it should already be established that the operand -// combination is valid, but returns false if operator can't work on operands. -// -bool TIntermBinary::promote(TInfoSink &infoSink) + +// Establishes the type of the result of the binary operation. +void TIntermBinary::promote() { - ASSERT(mLeft->isArray() == mRight->isArray()); + ASSERT(!isMultiplication() || + mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType())); - // // Base assumption: just make the type the same as the left // operand. Then only deviations from this need be coded. - // setType(mLeft->getType()); - // The result gets promoted to the highest precision. - TPrecision higherPrecision = GetHigherPrecision( - mLeft->getPrecision(), mRight->getPrecision()); - getTypePointer()->setPrecision(higherPrecision); - TQualifier resultQualifier = EvqConst; // Binary operations results in temporary variables unless both // operands are const. @@ -588,6 +811,55 @@ bool TIntermBinary::promote(TInfoSink &infoSink) getTypePointer()->setQualifier(EvqTemporary); } + // Handle indexing ops. + switch (mOp) + { + case EOpIndexDirect: + case EOpIndexIndirect: + if (mLeft->isArray()) + { + mType.clearArrayness(); + } + else if (mLeft->isMatrix()) + { + setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier, + static_cast<unsigned char>(mLeft->getRows()))); + } + else if (mLeft->isVector()) + { + setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier)); + } + else + { + UNREACHABLE(); + } + return; + case EOpIndexDirectStruct: + { + const TFieldList &fields = mLeft->getType().getStruct()->fields(); + const int i = mRight->getAsConstantUnion()->getIConst(0); + setType(*fields[i]->type()); + getTypePointer()->setQualifier(resultQualifier); + return; + } + case EOpIndexDirectInterfaceBlock: + { + const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields(); + const int i = mRight->getAsConstantUnion()->getIConst(0); + setType(*fields[i]->type()); + getTypePointer()->setQualifier(resultQualifier); + return; + } + default: + break; + } + + ASSERT(mLeft->isArray() == mRight->isArray()); + + // The result gets promoted to the highest precision. + TPrecision higherPrecision = GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision()); + getTypePointer()->setPrecision(higherPrecision); + const int nominalSize = std::max(mLeft->getNominalSize(), mRight->getNominalSize()); @@ -607,8 +879,8 @@ bool TIntermBinary::promote(TInfoSink &infoSink) case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: - setType(TType(EbtBool, EbpUndefined)); - break; + setType(TType(EbtBool, EbpUndefined, resultQualifier)); + break; // // And and Or operate on conditionals @@ -617,244 +889,210 @@ bool TIntermBinary::promote(TInfoSink &infoSink) case EOpLogicalXor: case EOpLogicalOr: ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool); - setType(TType(EbtBool, EbpUndefined)); + setType(TType(EbtBool, EbpUndefined, resultQualifier)); break; default: break; } - return true; + return; } // If we reach here, at least one of the operands is vector or matrix. // The other operand could be a scalar, vector, or matrix. - // Can these two operands be combined? - // TBasicType basicType = mLeft->getBasicType(); + switch (mOp) { - case EOpMul: - if (!mLeft->isMatrix() && mRight->isMatrix()) - { - if (mLeft->isVector()) - { - mOp = EOpVectorTimesMatrix; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast<unsigned char>(mRight->getCols()), 1)); - } - else + case EOpMul: + break; + case EOpMatrixTimesScalar: + if (mRight->isMatrix()) { - mOp = EOpMatrixTimesScalar; setType(TType(basicType, higherPrecision, resultQualifier, static_cast<unsigned char>(mRight->getCols()), static_cast<unsigned char>(mRight->getRows()))); } - } - else if (mLeft->isMatrix() && !mRight->isMatrix()) - { - if (mRight->isVector()) - { - mOp = EOpMatrixTimesVector; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast<unsigned char>(mLeft->getRows()), 1)); - } - else - { - mOp = EOpMatrixTimesScalar; - } - } - else if (mLeft->isMatrix() && mRight->isMatrix()) - { - mOp = EOpMatrixTimesMatrix; + break; + case EOpMatrixTimesVector: + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast<unsigned char>(mLeft->getRows()), 1)); + break; + case EOpMatrixTimesMatrix: setType(TType(basicType, higherPrecision, resultQualifier, static_cast<unsigned char>(mRight->getCols()), static_cast<unsigned char>(mLeft->getRows()))); + break; + case EOpVectorTimesScalar: + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast<unsigned char>(nominalSize), 1)); + break; + case EOpVectorTimesMatrix: + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast<unsigned char>(mRight->getCols()), 1)); + break; + case EOpMulAssign: + case EOpVectorTimesScalarAssign: + case EOpVectorTimesMatrixAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + ASSERT(mOp == GetMulAssignOpBasedOnOperands(mLeft->getType(), mRight->getType())); + break; + case EOpAssign: + case EOpInitialize: + ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && + (mLeft->getSecondarySize() == mRight->getSecondarySize())); + break; + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpIMod: + case EOpBitShiftLeft: + case EOpBitShiftRight: + case EOpBitwiseAnd: + case EOpBitwiseXor: + case EOpBitwiseOr: + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + case EOpIModAssign: + case EOpBitShiftLeftAssign: + case EOpBitShiftRightAssign: + case EOpBitwiseAndAssign: + case EOpBitwiseXorAssign: + case EOpBitwiseOrAssign: + { + const int secondarySize = + std::max(mLeft->getSecondarySize(), mRight->getSecondarySize()); + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast<unsigned char>(nominalSize), + static_cast<unsigned char>(secondarySize))); + ASSERT(!mLeft->isArray() && !mRight->isArray()); + break; } - else if (!mLeft->isMatrix() && !mRight->isMatrix()) - { - if (mLeft->isVector() && mRight->isVector()) - { - // leave as component product - } - else if (mLeft->isVector() || mRight->isVector()) - { - mOp = EOpVectorTimesScalar; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast<unsigned char>(nominalSize), 1)); - } - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Missing elses"); - return false; - } + case EOpEqual: + case EOpNotEqual: + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && + (mLeft->getSecondarySize() == mRight->getSecondarySize())); + setType(TType(EbtBool, EbpUndefined, resultQualifier)); + break; - if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType())) - { - return false; - } - break; + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectInterfaceBlock: + case EOpIndexDirectStruct: + // These ops should be already fully handled. + UNREACHABLE(); + break; + default: + UNREACHABLE(); + break; + } +} - case EOpMulAssign: - if (!mLeft->isMatrix() && mRight->isMatrix()) - { - if (mLeft->isVector()) - { - mOp = EOpVectorTimesMatrixAssign; - } - else - { - return false; - } - } - else if (mLeft->isMatrix() && !mRight->isMatrix()) +const TConstantUnion *TIntermConstantUnion::foldIndexing(int index) +{ + if (isArray()) + { + ASSERT(index < static_cast<int>(getType().getArraySize())); + TType arrayElementType = getType(); + arrayElementType.clearArrayness(); + size_t arrayElementSize = arrayElementType.getObjectSize(); + return &mUnionArrayPointer[arrayElementSize * index]; + } + else if (isMatrix()) + { + ASSERT(index < getType().getCols()); + int size = getType().getRows(); + return &mUnionArrayPointer[size * index]; + } + else if (isVector()) + { + ASSERT(index < getType().getNominalSize()); + return &mUnionArrayPointer[index]; + } + else + { + UNREACHABLE(); + return nullptr; + } +} + +TIntermTyped *TIntermSwizzle::fold() +{ + TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion(); + if (operandConstant == nullptr) + { + return nullptr; + } + + TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()]; + for (size_t i = 0; i < mSwizzleOffsets.size(); ++i) + { + constArray[i] = *operandConstant->foldIndexing(mSwizzleOffsets.at(i)); + } + return CreateFoldedNode(constArray, this, mType.getQualifier()); +} + +TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics) +{ + TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion(); + TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion(); + switch (mOp) + { + case EOpIndexDirect: { - if (mRight->isVector()) + if (leftConstant == nullptr || rightConstant == nullptr) { - return false; - } - else - { - mOp = EOpMatrixTimesScalarAssign; + return nullptr; } + int index = rightConstant->getIConst(0); + + const TConstantUnion *constArray = leftConstant->foldIndexing(index); + return CreateFoldedNode(constArray, this, mType.getQualifier()); } - else if (mLeft->isMatrix() && mRight->isMatrix()) - { - mOp = EOpMatrixTimesMatrixAssign; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast<unsigned char>(mRight->getCols()), - static_cast<unsigned char>(mLeft->getRows()))); - } - else if (!mLeft->isMatrix() && !mRight->isMatrix()) + case EOpIndexDirectStruct: { - if (mLeft->isVector() && mRight->isVector()) + if (leftConstant == nullptr || rightConstant == nullptr) { - // leave as component product + return nullptr; } - else if (mLeft->isVector() || mRight->isVector()) + const TFieldList &fields = mLeft->getType().getStruct()->fields(); + size_t index = static_cast<size_t>(rightConstant->getIConst(0)); + + size_t previousFieldsSize = 0; + for (size_t i = 0; i < index; ++i) { - if (!mLeft->isVector()) - return false; - mOp = EOpVectorTimesScalarAssign; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast<unsigned char>(mLeft->getNominalSize()), 1)); + previousFieldsSize += fields[i]->type()->getObjectSize(); } - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Missing elses"); - return false; - } - if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType())) - { - return false; + const TConstantUnion *constArray = leftConstant->getUnionArrayPointer(); + return CreateFoldedNode(constArray + previousFieldsSize, this, mType.getQualifier()); } - break; - - case EOpAssign: - case EOpInitialize: - // No more additional checks are needed. - ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && - (mLeft->getSecondarySize() == mRight->getSecondarySize())); - break; - case EOpAdd: - case EOpSub: - case EOpDiv: - case EOpIMod: - case EOpBitShiftLeft: - case EOpBitShiftRight: - case EOpBitwiseAnd: - case EOpBitwiseXor: - case EOpBitwiseOr: - case EOpAddAssign: - case EOpSubAssign: - case EOpDivAssign: - case EOpIModAssign: - case EOpBitShiftLeftAssign: - case EOpBitShiftRightAssign: - case EOpBitwiseAndAssign: - case EOpBitwiseXorAssign: - case EOpBitwiseOrAssign: - if ((mLeft->isMatrix() && mRight->isVector()) || - (mLeft->isVector() && mRight->isMatrix())) - { - return false; - } - - // Are the sizes compatible? - if (mLeft->getNominalSize() != mRight->getNominalSize() || - mLeft->getSecondarySize() != mRight->getSecondarySize()) - { - // If the nominal sizes of operands do not match: - // One of them must be a scalar. - if (!mLeft->isScalar() && !mRight->isScalar()) - return false; - - // In the case of compound assignment other than multiply-assign, - // the right side needs to be a scalar. Otherwise a vector/matrix - // would be assigned to a scalar. A scalar can't be shifted by a - // vector either. - if (!mRight->isScalar() && - (isAssignment() || - mOp == EOpBitShiftLeft || - mOp == EOpBitShiftRight)) - return false; - } - + case EOpIndexIndirect: + case EOpIndexDirectInterfaceBlock: + // Can never be constant folded. + return nullptr; + default: { - const int secondarySize = std::max( - mLeft->getSecondarySize(), mRight->getSecondarySize()); - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast<unsigned char>(nominalSize), - static_cast<unsigned char>(secondarySize))); - if (mLeft->isArray()) + if (leftConstant == nullptr || rightConstant == nullptr) { - ASSERT(mLeft->getArraySize() == mRight->getArraySize()); - mType.setArraySize(mLeft->getArraySize()); + return nullptr; } - } - break; - - case EOpEqual: - case EOpNotEqual: - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && - (mLeft->getSecondarySize() == mRight->getSecondarySize())); - setType(TType(EbtBool, EbpUndefined)); - break; - - default: - return false; - } - return true; -} - -TIntermTyped *TIntermBinary::fold(TInfoSink &infoSink) -{ - TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion(); - TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion(); - if (leftConstant == nullptr || rightConstant == nullptr) - { - return nullptr; - } - TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, infoSink); + TConstantUnion *constArray = + leftConstant->foldBinary(mOp, rightConstant, diagnostics, mLeft->getLine()); - // Nodes may be constant folded without being qualified as constant. - TQualifier resultQualifier = EvqConst; - if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst) - { - resultQualifier = EvqTemporary; + // Nodes may be constant folded without being qualified as constant. + return CreateFoldedNode(constArray, this, mType.getQualifier()); + } } - return CreateFoldedNode(constArray, this, resultQualifier); } -TIntermTyped *TIntermUnary::fold(TInfoSink &infoSink) +TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics) { TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion(); if (operandConstant == nullptr) @@ -877,19 +1115,18 @@ TIntermTyped *TIntermUnary::fold(TInfoSink &infoSink) case EOpUnpackUnorm2x16: case EOpPackHalf2x16: case EOpUnpackHalf2x16: - constArray = operandConstant->foldUnaryWithDifferentReturnType(mOp, infoSink); - break; + constArray = operandConstant->foldUnaryNonComponentWise(mOp); + break; default: - constArray = operandConstant->foldUnaryWithSameReturnType(mOp, infoSink); - break; + constArray = operandConstant->foldUnaryComponentWise(mOp, diagnostics); + break; } // Nodes may be constant folded without being qualified as constant. - TQualifier resultQualifier = mOperand->getQualifier() == EvqConst ? EvqConst : EvqTemporary; - return CreateFoldedNode(constArray, this, resultQualifier); + return CreateFoldedNode(constArray, this, mType.getQualifier()); } -TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink) +TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics) { // Make sure that all params are constant before actual constant folding. for (auto *param : *getSequence()) @@ -901,9 +1138,9 @@ TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink) } TConstantUnion *constArray = nullptr; if (isConstructor()) - constArray = TIntermConstantUnion::FoldAggregateConstructor(this, infoSink); + constArray = TIntermConstantUnion::FoldAggregateConstructor(this); else - constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, infoSink); + constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics); // Nodes may be constant folded without being qualified as constant. TQualifier resultQualifier = areChildrenConstQualified() ? EvqConst : EvqTemporary; @@ -916,15 +1153,15 @@ TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink) // // Returns the constant value to keep using or nullptr. // -TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, + TIntermConstantUnion *rightNode, + TDiagnostics *diagnostics, + const TSourceLoc &line) { const TConstantUnion *leftArray = getUnionArrayPointer(); const TConstantUnion *rightArray = rightNode->getUnionArrayPointer(); - if (!leftArray) - return nullptr; - if (!rightArray) - return nullptr; + ASSERT(leftArray && rightArray); size_t objectSize = getType().getObjectSize(); @@ -947,12 +1184,12 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EOpAdd: resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] + rightArray[i]; + resultArray[i] = TConstantUnion::add(leftArray[i], rightArray[i], diagnostics, line); break; case EOpSub: resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] - rightArray[i]; + resultArray[i] = TConstantUnion::sub(leftArray[i], rightArray[i], diagnostics, line); break; case EOpMul: @@ -960,19 +1197,13 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EOpMatrixTimesScalar: resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] * rightArray[i]; + resultArray[i] = TConstantUnion::mul(leftArray[i], rightArray[i], diagnostics, line); break; case EOpMatrixTimesMatrix: { - if (getType().getBasicType() != EbtFloat || - rightNode->getBasicType() != EbtFloat) - { - infoSink.info.message( - EPrefixInternalError, getLine(), - "Constant Folding cannot be done for matrix multiply"); - return nullptr; - } + // TODO(jmadll): This code should check for overflows. + ASSERT(getType().getBasicType() == EbtFloat && rightNode->getBasicType() == EbtFloat); const int leftCols = getCols(); const int leftRows = getRows(); @@ -1010,8 +1241,8 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EbtFloat: if (rightArray[i] == 0.0f) { - infoSink.info.message(EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); + diagnostics->warning( + getLine(), "Divide by zero error during constant folding", "/", ""); resultArray[i].setFConst(leftArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX); } else @@ -1024,20 +1255,48 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EbtInt: if (rightArray[i] == 0) { - infoSink.info.message(EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); + diagnostics->warning( + getLine(), "Divide by zero error during constant folding", "/", ""); resultArray[i].setIConst(INT_MAX); } else { + int lhs = leftArray[i].getIConst(); + int divisor = rightArray[i].getIConst(); if (op == EOpDiv) { - resultArray[i].setIConst(leftArray[i].getIConst() / rightArray[i].getIConst()); + // Check for the special case where the minimum representable number is + // divided by -1. If left alone this leads to integer overflow in C++. + // ESSL 3.00.6 section 4.1.3 Integers: + // "However, for the case where the minimum representable value is + // divided by -1, it is allowed to return either the minimum + // representable value or the maximum representable value." + if (lhs == -0x7fffffff - 1 && divisor == -1) + { + resultArray[i].setIConst(0x7fffffff); + } + else + { + resultArray[i].setIConst(lhs / divisor); + } } else { ASSERT(op == EOpIMod); - resultArray[i].setIConst(leftArray[i].getIConst() % rightArray[i].getIConst()); + if (lhs < 0 || divisor < 0) + { + // ESSL 3.00.6 section 5.9: Results of modulus are undefined when + // either one of the operands is negative. + diagnostics->warning(getLine(), + "Negative modulus operator operand " + "encountered during constant folding", + "%", ""); + resultArray[i].setIConst(0); + } + else + { + resultArray[i].setIConst(lhs % divisor); + } } } break; @@ -1045,8 +1304,8 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EbtUInt: if (rightArray[i] == 0) { - infoSink.info.message(EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); + diagnostics->warning( + getLine(), "Divide by zero error during constant folding", "/", ""); resultArray[i].setUConst(UINT_MAX); } else @@ -1064,9 +1323,8 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn break; default: - infoSink.info.message(EPrefixInternalError, getLine(), - "Constant folding cannot be done for \"/\""); - return nullptr; + UNREACHABLE(); + return nullptr; } } } @@ -1074,12 +1332,8 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EOpMatrixTimesVector: { - if (rightNode->getBasicType() != EbtFloat) - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Constant Folding cannot be done for matrix times vector"); - return nullptr; - } + // TODO(jmadll): This code should check for overflows. + ASSERT(rightNode->getBasicType() == EbtFloat); const int matrixCols = getCols(); const int matrixRows = getRows(); @@ -1101,12 +1355,8 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EOpVectorTimesMatrix: { - if (getType().getBasicType() != EbtFloat) - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Constant Folding cannot be done for vector times matrix"); - return nullptr; - } + // TODO(jmadll): This code should check for overflows. + ASSERT(getType().getBasicType() == EbtFloat); const int matrixCols = rightNode->getType().getCols(); const int matrixRows = rightNode->getType().getRows(); @@ -1148,18 +1398,11 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EOpLogicalXor: { + ASSERT(getType().getBasicType() == EbtBool); resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) { - switch (getType().getBasicType()) - { - case EbtBool: - resultArray[i].setBConst(leftArray[i] != rightArray[i]); - break; - default: - UNREACHABLE(); - break; - } + resultArray[i].setBConst(leftArray[i] != rightArray[i]); } } break; @@ -1182,12 +1425,12 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn case EOpBitShiftLeft: resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] << rightArray[i]; + resultArray[i] = TConstantUnion::lshift(leftArray[i], rightArray[i], diagnostics, line); break; case EOpBitShiftRight: resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] >> rightArray[i]; + resultArray[i] = TConstantUnion::rshift(leftArray[i], rightArray[i], diagnostics, line); break; case EOpLessThan: @@ -1239,37 +1482,28 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn break; default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Invalid operator for constant folding"); - return nullptr; + UNREACHABLE(); + return nullptr; } return resultArray; } -// -// The fold functions see if an operation on a constant can be done in place, -// without generating run-time code. -// -// Returns the constant value to keep using or nullptr. -// -TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink) +// The fold functions do operations on a constant at GLSL compile time, without generating run-time +// code. Returns the constant value to keep using. Nullptr should not be returned. +TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op) { - // - // Do operations where the return type has a different number of components compared to the operand type. - // + // Do operations where the return type may have a different number of components compared to the + // operand type. const TConstantUnion *operandArray = getUnionArrayPointer(); - if (!operandArray) - return nullptr; + ASSERT(operandArray); size_t objectSize = getType().getObjectSize(); TConstantUnion *resultArray = nullptr; switch (op) { - case EOpAny: - if (getType().getBasicType() == EbtBool) - { + case EOpAny: + ASSERT(getType().getBasicType() == EbtBool); resultArray = new TConstantUnion(); resultArray->setBConst(false); for (size_t i = 0; i < objectSize; i++) @@ -1281,16 +1515,9 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator } } break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpAll: - if (getType().getBasicType() == EbtBool) - { + case EOpAll: + ASSERT(getType().getBasicType() == EbtBool); resultArray = new TConstantUnion(); resultArray->setBConst(true); for (size_t i = 0; i < objectSize; i++) @@ -1302,89 +1529,55 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator } } break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpLength: - if (getType().getBasicType() == EbtFloat) - { + case EOpLength: + ASSERT(getType().getBasicType() == EbtFloat); resultArray = new TConstantUnion(); resultArray->setFConst(VectorLength(operandArray, objectSize)); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpTranspose: - if (getType().getBasicType() == EbtFloat) + case EOpTranspose: { + ASSERT(getType().getBasicType() == EbtFloat); resultArray = new TConstantUnion[objectSize]; angle::Matrix<float> result = - GetMatrix(operandArray, getType().getNominalSize(), getType().getSecondarySize()).transpose(); + GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose(); SetUnionArrayFromMatrix(result, resultArray); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpDeterminant: - if (getType().getBasicType() == EbtFloat) + case EOpDeterminant: { + ASSERT(getType().getBasicType() == EbtFloat); unsigned int size = getType().getNominalSize(); ASSERT(size >= 2 && size <= 4); resultArray = new TConstantUnion(); resultArray->setFConst(GetMatrix(operandArray, size).determinant()); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpInverse: - if (getType().getBasicType() == EbtFloat) + case EOpInverse: { + ASSERT(getType().getBasicType() == EbtFloat); unsigned int size = getType().getNominalSize(); ASSERT(size >= 2 && size <= 4); - resultArray = new TConstantUnion[objectSize]; + resultArray = new TConstantUnion[objectSize]; angle::Matrix<float> result = GetMatrix(operandArray, size).inverse(); SetUnionArrayFromMatrix(result, resultArray); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpPackSnorm2x16: - if (getType().getBasicType() == EbtFloat) - { + case EOpPackSnorm2x16: + ASSERT(getType().getBasicType() == EbtFloat); ASSERT(getType().getNominalSize() == 2); resultArray = new TConstantUnion(); - resultArray->setUConst(gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + resultArray->setUConst( + gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpUnpackSnorm2x16: - if (getType().getBasicType() == EbtUInt) + case EOpUnpackSnorm2x16: { + ASSERT(getType().getBasicType() == EbtUInt); resultArray = new TConstantUnion[2]; float f1, f2; gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2); @@ -1392,29 +1585,18 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator resultArray[1].setFConst(f2); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpPackUnorm2x16: - if (getType().getBasicType() == EbtFloat) - { + case EOpPackUnorm2x16: + ASSERT(getType().getBasicType() == EbtFloat); ASSERT(getType().getNominalSize() == 2); resultArray = new TConstantUnion(); - resultArray->setUConst(gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + resultArray->setUConst( + gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpUnpackUnorm2x16: - if (getType().getBasicType() == EbtUInt) + case EOpUnpackUnorm2x16: { + ASSERT(getType().getBasicType() == EbtUInt); resultArray = new TConstantUnion[2]; float f1, f2; gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2); @@ -1422,29 +1604,18 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator resultArray[1].setFConst(f2); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpPackHalf2x16: - if (getType().getBasicType() == EbtFloat) - { + case EOpPackHalf2x16: + ASSERT(getType().getBasicType() == EbtFloat); ASSERT(getType().getNominalSize() == 2); resultArray = new TConstantUnion(); - resultArray->setUConst(gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + resultArray->setUConst( + gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpUnpackHalf2x16: - if (getType().getBasicType() == EbtUInt) + case EOpUnpackHalf2x16: { + ASSERT(getType().getBasicType() == EbtUInt); resultArray = new TConstantUnion[2]; float f1, f2; gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2); @@ -1452,29 +1623,24 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator resultArray[1].setFConst(f2); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - break; - default: - break; + default: + UNREACHABLE(); + break; } return resultArray; } -TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op, + TDiagnostics *diagnostics) { - // - // Do unary operations where the return type is the same as operand type. - // + // Do unary operations where each component of the result is computed based on the corresponding + // component of the operand. Also folds normalize, though the divisor in that case takes all + // components into account. const TConstantUnion *operandArray = getUnionArrayPointer(); - if (!operandArray) - return nullptr; + ASSERT(operandArray); size_t objectSize = getType().getObjectSize(); @@ -1483,243 +1649,232 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, { switch(op) { - case EOpNegative: - switch (getType().getBasicType()) - { - case EbtFloat: - resultArray[i].setFConst(-operandArray[i].getFConst()); - break; - case EbtInt: - resultArray[i].setIConst(-operandArray[i].getIConst()); - break; - case EbtUInt: - resultArray[i].setUConst(static_cast<unsigned int>( - -static_cast<int>(operandArray[i].getUConst()))); + case EOpNegative: + switch (getType().getBasicType()) + { + case EbtFloat: + resultArray[i].setFConst(-operandArray[i].getFConst()); + break; + case EbtInt: + if (operandArray[i] == std::numeric_limits<int>::min()) + { + // The minimum representable integer doesn't have a positive + // counterpart, rather the negation overflows and in ESSL is supposed to + // wrap back to the minimum representable integer. Make sure that we + // don't actually let the negation overflow, which has undefined + // behavior in C++. + resultArray[i].setIConst(std::numeric_limits<int>::min()); + } + else + { + resultArray[i].setIConst(-operandArray[i].getIConst()); + } + break; + case EbtUInt: + if (operandArray[i] == 0x80000000u) + { + resultArray[i].setUConst(0x80000000u); + } + else + { + resultArray[i].setUConst(static_cast<unsigned int>( + -static_cast<int>(operandArray[i].getUConst()))); + } + break; + default: + UNREACHABLE(); + return nullptr; + } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpPositive: - switch (getType().getBasicType()) - { - case EbtFloat: - resultArray[i].setFConst(operandArray[i].getFConst()); - break; - case EbtInt: - resultArray[i].setIConst(operandArray[i].getIConst()); - break; - case EbtUInt: - resultArray[i].setUConst(static_cast<unsigned int>( - static_cast<int>(operandArray[i].getUConst()))); + case EOpPositive: + switch (getType().getBasicType()) + { + case EbtFloat: + resultArray[i].setFConst(operandArray[i].getFConst()); + break; + case EbtInt: + resultArray[i].setIConst(operandArray[i].getIConst()); + break; + case EbtUInt: + resultArray[i].setUConst(static_cast<unsigned int>( + static_cast<int>(operandArray[i].getUConst()))); + break; + default: + UNREACHABLE(); + return nullptr; + } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpLogicalNot: - // this code is written for possible future use, - // will not get executed currently - switch (getType().getBasicType()) - { - case EbtBool: - resultArray[i].setBConst(!operandArray[i].getBConst()); + case EOpLogicalNot: + switch (getType().getBasicType()) + { + case EbtBool: + resultArray[i].setBConst(!operandArray[i].getBConst()); + break; + default: + UNREACHABLE(); + return nullptr; + } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpBitwiseNot: - switch (getType().getBasicType()) - { - case EbtInt: - resultArray[i].setIConst(~operandArray[i].getIConst()); - break; - case EbtUInt: - resultArray[i].setUConst(~operandArray[i].getUConst()); + case EOpBitwiseNot: + switch (getType().getBasicType()) + { + case EbtInt: + resultArray[i].setIConst(~operandArray[i].getIConst()); + break; + case EbtUInt: + resultArray[i].setUConst(~operandArray[i].getUConst()); + break; + default: + UNREACHABLE(); + return nullptr; + } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpRadians: - if (getType().getBasicType() == EbtFloat) - { + case EOpRadians: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst()); break; - } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpDegrees: - if (getType().getBasicType() == EbtFloat) - { + case EOpDegrees: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst()); break; - } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - - case EOpSin: - if (!foldFloatTypeUnary(operandArray[i], &sinf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpCos: - if (!foldFloatTypeUnary(operandArray[i], &cosf, infoSink, &resultArray[i])) - return nullptr; - break; - case EOpTan: - if (!foldFloatTypeUnary(operandArray[i], &tanf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpSin: + foldFloatTypeUnary(operandArray[i], &sinf, &resultArray[i]); + break; - case EOpAsin: - // For asin(x), results are undefined if |x| > 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &asinf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpCos: + foldFloatTypeUnary(operandArray[i], &cosf, &resultArray[i]); + break; - case EOpAcos: - // For acos(x), results are undefined if |x| > 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &acosf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpTan: + foldFloatTypeUnary(operandArray[i], &tanf, &resultArray[i]); + break; - case EOpAtan: - if (!foldFloatTypeUnary(operandArray[i], &atanf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpAsin: + // For asin(x), results are undefined if |x| > 1, we are choosing to set result to + // 0. + if (fabsf(operandArray[i].getFConst()) > 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &asinf, &resultArray[i]); + break; - case EOpSinh: - if (!foldFloatTypeUnary(operandArray[i], &sinhf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpAcos: + // For acos(x), results are undefined if |x| > 1, we are choosing to set result to + // 0. + if (fabsf(operandArray[i].getFConst()) > 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &acosf, &resultArray[i]); + break; - case EOpCosh: - if (!foldFloatTypeUnary(operandArray[i], &coshf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpAtan: + foldFloatTypeUnary(operandArray[i], &atanf, &resultArray[i]); + break; - case EOpTanh: - if (!foldFloatTypeUnary(operandArray[i], &tanhf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpSinh: + foldFloatTypeUnary(operandArray[i], &sinhf, &resultArray[i]); + break; - case EOpAsinh: - if (!foldFloatTypeUnary(operandArray[i], &asinhf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpCosh: + foldFloatTypeUnary(operandArray[i], &coshf, &resultArray[i]); + break; - case EOpAcosh: - // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &acoshf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpTanh: + foldFloatTypeUnary(operandArray[i], &tanhf, &resultArray[i]); + break; - case EOpAtanh: - // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) >= 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &atanhf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpAsinh: + foldFloatTypeUnary(operandArray[i], &asinhf, &resultArray[i]); + break; - case EOpAbs: - switch (getType().getBasicType()) - { - case EbtFloat: - resultArray[i].setFConst(fabsf(operandArray[i].getFConst())); + case EOpAcosh: + // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0. + if (operandArray[i].getFConst() < 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &acoshf, &resultArray[i]); break; - case EbtInt: - resultArray[i].setIConst(abs(operandArray[i].getIConst())); + + case EOpAtanh: + // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to + // 0. + if (fabsf(operandArray[i].getFConst()) >= 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &atanhf, &resultArray[i]); break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpSign: - switch (getType().getBasicType()) - { - case EbtFloat: + case EOpAbs: + switch (getType().getBasicType()) { - float fConst = operandArray[i].getFConst(); - float fResult = 0.0f; - if (fConst > 0.0f) - fResult = 1.0f; - else if (fConst < 0.0f) - fResult = -1.0f; - resultArray[i].setFConst(fResult); + case EbtFloat: + resultArray[i].setFConst(fabsf(operandArray[i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst(abs(operandArray[i].getIConst())); + break; + default: + UNREACHABLE(); + return nullptr; } break; - case EbtInt: + + case EOpSign: + switch (getType().getBasicType()) { - int iConst = operandArray[i].getIConst(); - int iResult = 0; - if (iConst > 0) - iResult = 1; - else if (iConst < 0) - iResult = -1; - resultArray[i].setIConst(iResult); + case EbtFloat: + { + float fConst = operandArray[i].getFConst(); + float fResult = 0.0f; + if (fConst > 0.0f) + fResult = 1.0f; + else if (fConst < 0.0f) + fResult = -1.0f; + resultArray[i].setFConst(fResult); + break; + } + case EbtInt: + { + int iConst = operandArray[i].getIConst(); + int iResult = 0; + if (iConst > 0) + iResult = 1; + else if (iConst < 0) + iResult = -1; + resultArray[i].setIConst(iResult); + break; + } + default: + UNREACHABLE(); + return nullptr; } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpFloor: - if (!foldFloatTypeUnary(operandArray[i], &floorf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpFloor: + foldFloatTypeUnary(operandArray[i], &floorf, &resultArray[i]); + break; - case EOpTrunc: - if (!foldFloatTypeUnary(operandArray[i], &truncf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpTrunc: + foldFloatTypeUnary(operandArray[i], &truncf, &resultArray[i]); + break; - case EOpRound: - if (!foldFloatTypeUnary(operandArray[i], &roundf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpRound: + foldFloatTypeUnary(operandArray[i], &roundf, &resultArray[i]); + break; - case EOpRoundEven: - if (getType().getBasicType() == EbtFloat) + case EOpRoundEven: { + ASSERT(getType().getBasicType() == EbtFloat); float x = operandArray[i].getFConst(); float result; float fractPart = modff(x, &result); @@ -1730,197 +1885,151 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, resultArray[i].setFConst(result); break; } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpCeil: - if (!foldFloatTypeUnary(operandArray[i], &ceilf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpCeil: + foldFloatTypeUnary(operandArray[i], &ceilf, &resultArray[i]); + break; - case EOpFract: - if (getType().getBasicType() == EbtFloat) + case EOpFract: { + ASSERT(getType().getBasicType() == EbtFloat); float x = operandArray[i].getFConst(); resultArray[i].setFConst(x - floorf(x)); break; } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpIsNan: - if (getType().getBasicType() == EbtFloat) - { + case EOpIsNan: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpIsInf: - if (getType().getBasicType() == EbtFloat) - { + case EOpIsInf: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpFloatBitsToInt: - if (getType().getBasicType() == EbtFloat) - { + case EOpFloatBitsToInt: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setIConst(gl::bitCast<int32_t>(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpFloatBitsToUint: - if (getType().getBasicType() == EbtFloat) - { + case EOpFloatBitsToUint: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setUConst(gl::bitCast<uint32_t>(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpIntBitsToFloat: - if (getType().getBasicType() == EbtInt) - { + case EOpIntBitsToFloat: + ASSERT(getType().getBasicType() == EbtInt); resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getIConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpUintBitsToFloat: - if (getType().getBasicType() == EbtUInt) - { + case EOpUintBitsToFloat: + ASSERT(getType().getBasicType() == EbtUInt); resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getUConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpExp: - if (!foldFloatTypeUnary(operandArray[i], &expf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpExp: + foldFloatTypeUnary(operandArray[i], &expf, &resultArray[i]); + break; - case EOpLog: - // For log(x), results are undefined if x <= 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpLog: + // For log(x), results are undefined if x <= 0, we are choosing to set result to 0. + if (operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]); + break; - case EOpExp2: - if (!foldFloatTypeUnary(operandArray[i], &exp2f, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpExp2: + foldFloatTypeUnary(operandArray[i], &exp2f, &resultArray[i]); + break; - case EOpLog2: - // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0. - // And log2f is not available on some plarforms like old android, so just using log(x)/log(2) here. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i])) - return nullptr; - else - resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f)); - break; + case EOpLog2: + // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0. + // And log2f is not available on some plarforms like old android, so just using + // log(x)/log(2) here. + if (operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + { + foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]); + resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f)); + } + break; - case EOpSqrt: - // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpSqrt: + // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0. + if (operandArray[i].getFConst() < 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]); + break; - case EOpInverseSqrt: - // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(), - // so getting the square root first using builtin function sqrt() and then taking its inverse. - // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i])) - return nullptr; - else - resultArray[i].setFConst(1.0f / resultArray[i].getFConst()); - break; + case EOpInverseSqrt: + // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(), + // so getting the square root first using builtin function sqrt() and then taking + // its inverse. + // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set + // result to 0. + if (operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + { + foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]); + resultArray[i].setFConst(1.0f / resultArray[i].getFConst()); + } + break; - case EOpVectorLogicalNot: - if (getType().getBasicType() == EbtBool) - { + case EOpVectorLogicalNot: + ASSERT(getType().getBasicType() == EbtBool); resultArray[i].setBConst(!operandArray[i].getBConst()); break; - } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpNormalize: - if (getType().getBasicType() == EbtFloat) + case EOpNormalize: { - float x = operandArray[i].getFConst(); + ASSERT(getType().getBasicType() == EbtFloat); + float x = operandArray[i].getFConst(); float length = VectorLength(operandArray, objectSize); if (length) resultArray[i].setFConst(x / length); else - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, - &resultArray[i]); + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); break; } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpDFdx: - case EOpDFdy: - case EOpFwidth: - if (getType().getBasicType() == EbtFloat) - { + case EOpDFdx: + case EOpDFdy: + case EOpFwidth: + ASSERT(getType().getBasicType() == EbtFloat); // Derivatives of constant arguments should be 0. resultArray[i].setFConst(0.0f); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - default: - return nullptr; + default: + return nullptr; } } return resultArray; } -bool TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion ¶meter, FloatTypeUnaryFunc builtinFunc, - TInfoSink &infoSink, TConstantUnion *result) const +void TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion ¶meter, + FloatTypeUnaryFunc builtinFunc, + TConstantUnion *result) const { ASSERT(builtinFunc); - if (getType().getBasicType() == EbtFloat) - { - result->setFConst(builtinFunc(parameter.getFConst())); - return true; - } - - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return false; + ASSERT(getType().getBasicType() == EbtFloat); + result->setFConst(builtinFunc(parameter.getFConst())); } // static -TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate *aggregate, - TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate *aggregate) { ASSERT(aggregate->getSequence()->size() > 0u); size_t resultSize = aggregate->getType().getObjectSize(); @@ -2019,7 +2128,8 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate } // static -TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate, + TDiagnostics *diagnostics) { TOperator op = aggregate->getOp(); TIntermSequence *sequence = aggregate->getSequence(); @@ -2045,7 +2155,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg maxObjectSize = objectSizes[i]; } - if (!(*sequence)[0]->getAsTyped()->isMatrix()) + if (!(*sequence)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct) { for (unsigned int i = 0; i < paramsCount; i++) if (objectSizes[i] != maxObjectSize) @@ -2060,284 +2170,298 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg // switch (op) { - case EOpAtan: + case EOpAtan: { - if (basicType == EbtFloat) + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float y = unionArrays[0][i].getFConst(); - float x = unionArrays[1][i].getFConst(); - // Results are undefined if x and y are both 0. - if (x == 0.0f && y == 0.0f) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else - resultArray[i].setFConst(atan2f(y, x)); - } + float y = unionArrays[0][i].getFConst(); + float x = unionArrays[1][i].getFConst(); + // Results are undefined if x and y are both 0. + if (x == 0.0f && y == 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); + else + resultArray[i].setFConst(atan2f(y, x)); } - else - UNREACHABLE(); + break; } - break; - case EOpPow: + case EOpPow: { - if (basicType == EbtFloat) + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float x = unionArrays[0][i].getFConst(); - float y = unionArrays[1][i].getFConst(); - // Results are undefined if x < 0. - // Results are undefined if x = 0 and y <= 0. - if (x < 0.0f) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else if (x == 0.0f && y <= 0.0f) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else - resultArray[i].setFConst(powf(x, y)); - } + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + // Results are undefined if x < 0. + // Results are undefined if x = 0 and y <= 0. + if (x < 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); + else if (x == 0.0f && y <= 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); + else + resultArray[i].setFConst(powf(x, y)); } - else - UNREACHABLE(); + break; } - break; - case EOpMod: + case EOpMod: { - if (basicType == EbtFloat) + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float x = unionArrays[0][i].getFConst(); - float y = unionArrays[1][i].getFConst(); - resultArray[i].setFConst(x - y * floorf(x / y)); - } + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + resultArray[i].setFConst(x - y * floorf(x / y)); } - else - UNREACHABLE(); + break; } - break; - case EOpMin: + case EOpMin: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setFConst(std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); - break; - case EbtInt: - resultArray[i].setIConst(std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); - break; - case EbtUInt: - resultArray[i].setUConst(std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setFConst(std::min(unionArrays[0][i].getFConst(), + unionArrays[1][i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst(std::min(unionArrays[0][i].getIConst(), + unionArrays[1][i].getIConst())); + break; + case EbtUInt: + resultArray[i].setUConst(std::min(unionArrays[0][i].getUConst(), + unionArrays[1][i].getUConst())); + break; + default: + UNREACHABLE(); + break; } } + break; } - break; - case EOpMax: + case EOpMax: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setFConst(std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); - break; - case EbtInt: - resultArray[i].setIConst(std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); - break; - case EbtUInt: - resultArray[i].setUConst(std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setFConst(std::max(unionArrays[0][i].getFConst(), + unionArrays[1][i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst(std::max(unionArrays[0][i].getIConst(), + unionArrays[1][i].getIConst())); + break; + case EbtUInt: + resultArray[i].setUConst(std::max(unionArrays[0][i].getUConst(), + unionArrays[1][i].getUConst())); + break; + default: + UNREACHABLE(); + break; } } + break; } - break; - case EOpStep: + case EOpStep: { - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - resultArray[i].setFConst(unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f); - } - else - UNREACHABLE(); + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + resultArray[i].setFConst( + unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f + : 1.0f); + break; } - break; - case EOpLessThan: + case EOpLessThan: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() < unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() < unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() < unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() < + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() < + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() < + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; } } + break; } - break; - case EOpLessThanEqual: + case EOpLessThanEqual: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() <= unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() <= unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() <= unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() <= + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() <= + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() <= + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; } } + break; } - break; - case EOpGreaterThan: + case EOpGreaterThan: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() > unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() > unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() > unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() > + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() > + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() > + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; } } + break; } - break; - - case EOpGreaterThanEqual: + case EOpGreaterThanEqual: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() >= unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() >= unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() >= unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() >= + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() >= + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() >= + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; } } } break; - case EOpVectorEqual: + case EOpVectorEqual: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() == unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() == unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() == unionArrays[1][i].getUConst()); - break; - case EbtBool: - resultArray[i].setBConst(unionArrays[0][i].getBConst() == unionArrays[1][i].getBConst()); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() == + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() == + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() == + unionArrays[1][i].getUConst()); + break; + case EbtBool: + resultArray[i].setBConst(unionArrays[0][i].getBConst() == + unionArrays[1][i].getBConst()); + break; + default: + UNREACHABLE(); + break; } } + break; } - break; - case EOpVectorNotEqual: + case EOpVectorNotEqual: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() != unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() != unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() != unionArrays[1][i].getUConst()); - break; - case EbtBool: - resultArray[i].setBConst(unionArrays[0][i].getBConst() != unionArrays[1][i].getBConst()); - break; - default: - UNREACHABLE(); - break; + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() != + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() != + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() != + unionArrays[1][i].getUConst()); + break; + case EbtBool: + resultArray[i].setBConst(unionArrays[0][i].getBConst() != + unionArrays[1][i].getBConst()); + break; + default: + UNREACHABLE(); + break; } } + break; } - break; - case EOpDistance: - if (basicType == EbtFloat) + case EOpDistance: { + ASSERT(basicType == EbtFloat); TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize]; - resultArray = new TConstantUnion(); + resultArray = new TConstantUnion(); for (size_t i = 0; i < maxObjectSize; i++) { float x = unionArrays[0][i].getFConst(); @@ -2345,47 +2469,40 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg distanceArray[i].setFConst(x - y); } resultArray->setFConst(VectorLength(distanceArray, maxObjectSize)); + break; } - else - UNREACHABLE(); - break; - case EOpDot: - - if (basicType == EbtFloat) - { + case EOpDot: + ASSERT(basicType == EbtFloat); resultArray = new TConstantUnion(); - resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize)); - } - else - UNREACHABLE(); - break; + resultArray->setFConst( + VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize)); + break; - case EOpCross: - if (basicType == EbtFloat && maxObjectSize == 3) + case EOpCross: { + ASSERT(basicType == EbtFloat && maxObjectSize == 3); resultArray = new TConstantUnion[maxObjectSize]; - float x0 = unionArrays[0][0].getFConst(); - float x1 = unionArrays[0][1].getFConst(); - float x2 = unionArrays[0][2].getFConst(); - float y0 = unionArrays[1][0].getFConst(); - float y1 = unionArrays[1][1].getFConst(); - float y2 = unionArrays[1][2].getFConst(); + float x0 = unionArrays[0][0].getFConst(); + float x1 = unionArrays[0][1].getFConst(); + float x2 = unionArrays[0][2].getFConst(); + float y0 = unionArrays[1][0].getFConst(); + float y1 = unionArrays[1][1].getFConst(); + float y2 = unionArrays[1][2].getFConst(); resultArray[0].setFConst(x1 * y2 - y1 * x2); resultArray[1].setFConst(x2 * y0 - y2 * x0); resultArray[2].setFConst(x0 * y1 - y0 * x1); + break; } - else - UNREACHABLE(); - break; - case EOpReflect: - if (basicType == EbtFloat) + case EOpReflect: { + ASSERT(basicType == EbtFloat); // genType reflect (genType I, genType N) : - // For the incident vector I and surface orientation N, returns the reflection direction: + // For the incident vector I and surface orientation N, returns the reflection + // direction: // I - 2 * dot(N, I) * N. - resultArray = new TConstantUnion[maxObjectSize]; + resultArray = new TConstantUnion[maxObjectSize]; float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); for (size_t i = 0; i < maxObjectSize; i++) { @@ -2393,45 +2510,40 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg 2.0f * dotProduct * unionArrays[1][i].getFConst(); resultArray[i].setFConst(result); } + break; } - else - UNREACHABLE(); - break; - case EOpMul: - if (basicType == EbtFloat && (*sequence)[0]->getAsTyped()->isMatrix() && - (*sequence)[1]->getAsTyped()->isMatrix()) + case EOpMul: { + ASSERT(basicType == EbtFloat && (*sequence)[0]->getAsTyped()->isMatrix() && + (*sequence)[1]->getAsTyped()->isMatrix()); // Perform component-wise matrix multiplication. resultArray = new TConstantUnion[maxObjectSize]; - int size = (*sequence)[0]->getAsTyped()->getNominalSize(); + int size = (*sequence)[0]->getAsTyped()->getNominalSize(); angle::Matrix<float> result = GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size)); SetUnionArrayFromMatrix(result, resultArray); + break; } - else - UNREACHABLE(); - break; - case EOpOuterProduct: - if (basicType == EbtFloat) + case EOpOuterProduct: { + ASSERT(basicType == EbtFloat); size_t numRows = (*sequence)[0]->getAsTyped()->getType().getObjectSize(); size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize(); - resultArray = new TConstantUnion[numRows * numCols]; + resultArray = new TConstantUnion[numRows * numCols]; angle::Matrix<float> result = - GetMatrix(unionArrays[0], 1, static_cast<int>(numCols)) - .outerProduct(GetMatrix(unionArrays[1], static_cast<int>(numRows), 1)); + GetMatrix(unionArrays[0], static_cast<int>(numRows), 1) + .outerProduct(GetMatrix(unionArrays[1], 1, static_cast<int>(numCols))); SetUnionArrayFromMatrix(result, resultArray); + break; } - else - UNREACHABLE(); - break; - default: - UNREACHABLE(); - // TODO: Add constant folding support for other built-in operations that take 2 parameters and not handled above. - return nullptr; + default: + UNREACHABLE(); + // TODO: Add constant folding support for other built-in operations that take 2 + // parameters and not handled above. + return nullptr; } } else if (paramsCount == 3) @@ -2441,124 +2553,123 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg // switch (op) { - case EOpClamp: + case EOpClamp: { resultArray = new TConstantUnion[maxObjectSize]; for (size_t i = 0; i < maxObjectSize; i++) { switch (basicType) { - case EbtFloat: + case EbtFloat: { - float x = unionArrays[0][i].getFConst(); + float x = unionArrays[0][i].getFConst(); float min = unionArrays[1][i].getFConst(); float max = unionArrays[2][i].getFConst(); // Results are undefined if min > max. if (min > max) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); else resultArray[i].setFConst(gl::clamp(x, min, max)); + break; } - break; - case EbtInt: + + case EbtInt: { - int x = unionArrays[0][i].getIConst(); + int x = unionArrays[0][i].getIConst(); int min = unionArrays[1][i].getIConst(); int max = unionArrays[2][i].getIConst(); // Results are undefined if min > max. if (min > max) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); else resultArray[i].setIConst(gl::clamp(x, min, max)); + break; } - break; - case EbtUInt: + case EbtUInt: { - unsigned int x = unionArrays[0][i].getUConst(); + unsigned int x = unionArrays[0][i].getUConst(); unsigned int min = unionArrays[1][i].getUConst(); unsigned int max = unionArrays[2][i].getUConst(); // Results are undefined if min > max. if (min > max) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); else resultArray[i].setUConst(gl::clamp(x, min, max)); + break; } - break; - default: - UNREACHABLE(); - break; + default: + UNREACHABLE(); + break; } } + break; } - break; - case EOpMix: + case EOpMix: { - if (basicType == EbtFloat) + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + TBasicType type = (*sequence)[2]->getAsTyped()->getType().getBasicType(); + if (type == EbtFloat) { - float x = unionArrays[0][i].getFConst(); - float y = unionArrays[1][i].getFConst(); - TBasicType type = (*sequence)[2]->getAsTyped()->getType().getBasicType(); - if (type == EbtFloat) - { - // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a. - float a = unionArrays[2][i].getFConst(); - resultArray[i].setFConst(x * (1.0f - a) + y * a); - } - else // 3rd parameter is EbtBool - { - ASSERT(type == EbtBool); - // Selects which vector each returned component comes from. - // For a component of a that is false, the corresponding component of x is returned. - // For a component of a that is true, the corresponding component of y is returned. - bool a = unionArrays[2][i].getBConst(); - resultArray[i].setFConst(a ? y : x); - } + // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a. + float a = unionArrays[2][i].getFConst(); + resultArray[i].setFConst(x * (1.0f - a) + y * a); + } + else // 3rd parameter is EbtBool + { + ASSERT(type == EbtBool); + // Selects which vector each returned component comes from. + // For a component of a that is false, the corresponding component of x is + // returned. + // For a component of a that is true, the corresponding component of y is + // returned. + bool a = unionArrays[2][i].getBConst(); + resultArray[i].setFConst(a ? y : x); } } - else - UNREACHABLE(); + break; } - break; - case EOpSmoothStep: + case EOpSmoothStep: { - if (basicType == EbtFloat) + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) + float edge0 = unionArrays[0][i].getFConst(); + float edge1 = unionArrays[1][i].getFConst(); + float x = unionArrays[2][i].getFConst(); + // Results are undefined if edge0 >= edge1. + if (edge0 >= edge1) { - float edge0 = unionArrays[0][i].getFConst(); - float edge1 = unionArrays[1][i].getFConst(); - float x = unionArrays[2][i].getFConst(); - // Results are undefined if edge0 >= edge1. - if (edge0 >= edge1) - { - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - } - else - { - // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth - // Hermite interpolation between 0 and 1 when edge0 < x < edge1. - float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); - resultArray[i].setFConst(t * t * (3.0f - 2.0f * t)); - } + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); + } + else + { + // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth + // Hermite interpolation between 0 and 1 when edge0 < x < edge1. + float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); + resultArray[i].setFConst(t * t * (3.0f - 2.0f * t)); } } - else - UNREACHABLE(); + break; } - break; - case EOpFaceForward: - if (basicType == EbtFloat) + case EOpFaceForward: { + ASSERT(basicType == EbtFloat); // genType faceforward(genType N, genType I, genType Nref) : // If dot(Nref, I) < 0 return N, otherwise return -N. - resultArray = new TConstantUnion[maxObjectSize]; + resultArray = new TConstantUnion[maxObjectSize]; float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize); for (size_t i = 0; i < maxObjectSize; i++) { @@ -2567,43 +2678,42 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *agg else resultArray[i].setFConst(-unionArrays[0][i].getFConst()); } + break; } - else - UNREACHABLE(); - break; - case EOpRefract: - if (basicType == EbtFloat) + case EOpRefract: { + ASSERT(basicType == EbtFloat); // genType refract(genType I, genType N, float eta) : - // For the incident vector I and surface normal N, and the ratio of indices of refraction eta, + // For the incident vector I and surface normal N, and the ratio of indices of + // refraction eta, // return the refraction vector. The result is computed by // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) // if (k < 0.0) // return genType(0.0) // else // return eta * I - (eta * dot(N, I) + sqrt(k)) * N - resultArray = new TConstantUnion[maxObjectSize]; + resultArray = new TConstantUnion[maxObjectSize]; float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); for (size_t i = 0; i < maxObjectSize; i++) { float eta = unionArrays[2][i].getFConst(); - float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct); + float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct); if (k < 0.0f) resultArray[i].setFConst(0.0f); else resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() - - (eta * dotProduct + sqrtf(k)) * unionArrays[1][i].getFConst()); + (eta * dotProduct + sqrtf(k)) * + unionArrays[1][i].getFConst()); } + break; } - else - UNREACHABLE(); - break; - default: - UNREACHABLE(); - // TODO: Add constant folding support for other built-in operations that take 3 parameters and not handled above. - return nullptr; + default: + UNREACHABLE(); + // TODO: Add constant folding support for other built-in operations that take 3 + // parameters and not handled above. + return nullptr; } } return resultArray; @@ -2675,7 +2785,28 @@ void TIntermTraverser::updateTree() UNUSED_ASSERTION_VARIABLE(replaced); } - mInsertions.clear(); + clearReplacementQueue(); +} + +void TIntermTraverser::clearReplacementQueue() +{ mReplacements.clear(); mMultiReplacements.clear(); + mInsertions.clear(); +} + +void TIntermTraverser::queueReplacement(TIntermNode *original, + TIntermNode *replacement, + OriginalNode originalStatus) +{ + queueReplacementWithParent(getParentNode(), original, replacement, originalStatus); +} + +void TIntermTraverser::queueReplacementWithParent(TIntermNode *parent, + TIntermNode *original, + TIntermNode *replacement, + OriginalNode originalStatus) +{ + bool originalBecomesChild = (originalStatus == OriginalNode::BECOMES_CHILD); + mReplacements.push_back(NodeUpdateEntry(parent, original, replacement, originalBecomesChild)); } diff --git a/chromium/third_party/angle/src/compiler/translator/IntermNode.h b/chromium/third_party/angle/src/compiler/translator/IntermNode.h index 58c8c74379e..f261e76aca3 100644 --- a/chromium/third_party/angle/src/compiler/translator/IntermNode.h +++ b/chromium/third_party/angle/src/compiler/translator/IntermNode.h @@ -27,12 +27,16 @@ #include "compiler/translator/Operator.h" #include "compiler/translator/Types.h" +class TDiagnostics; + class TIntermTraverser; class TIntermAggregate; +class TIntermSwizzle; class TIntermBinary; class TIntermUnary; class TIntermConstantUnion; -class TIntermSelection; +class TIntermTernary; +class TIntermIfElse; class TIntermSwitch; class TIntermCase; class TIntermTyped; @@ -89,9 +93,11 @@ class TIntermNode : angle::NonCopyable virtual TIntermTyped *getAsTyped() { return 0; } virtual TIntermConstantUnion *getAsConstantUnion() { return 0; } virtual TIntermAggregate *getAsAggregate() { return 0; } + virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; } virtual TIntermBinary *getAsBinaryNode() { return 0; } virtual TIntermUnary *getAsUnaryNode() { return 0; } - virtual TIntermSelection *getAsSelectionNode() { return 0; } + virtual TIntermTernary *getAsTernaryNode() { return nullptr; } + virtual TIntermIfElse *getAsIfElseNode() { return nullptr; } virtual TIntermSwitch *getAsSwitchNode() { return 0; } virtual TIntermCase *getAsCaseNode() { return 0; } virtual TIntermSymbol *getAsSymbolNode() { return 0; } @@ -153,10 +159,13 @@ class TIntermTyped : public TIntermNode const char *getBasicString() const { return mType.getBasicString(); } TString getCompleteString() const { return mType.getCompleteString(); } - int getArraySize() const { return mType.getArraySize(); } + unsigned int getArraySize() const { return mType.getArraySize(); } bool isConstructorWithOnlyConstantUnionParameters(); + static TIntermTyped *CreateIndexNode(int index); + static TIntermTyped *CreateZero(const TType &type); + protected: TType mType; @@ -195,6 +204,10 @@ class TIntermLoop : public TIntermNode TIntermTyped *getExpression() { return mExpr; } TIntermAggregate *getBody() { return mBody; } + void setCondition(TIntermTyped *condition) { mCond = condition; } + void setExpression(TIntermTyped *expression) { mExpr = expression; } + void setBody(TIntermAggregate *body) { mBody = body; } + void setUnrollFlag(bool flag) { mUnrollFlag = flag; } bool getUnrollFlag() const { return mUnrollFlag; } @@ -310,6 +323,7 @@ class TIntermConstantUnion : public TIntermTyped TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type) : TIntermTyped(type), mUnionArrayPointer(unionPointer) { + ASSERT(unionPointer); } TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); } @@ -337,6 +351,7 @@ class TIntermConstantUnion : public TIntermTyped void replaceConstantUnion(const TConstantUnion *safeConstantUnion) { + ASSERT(safeConstantUnion); // Previous union pointer freed on pool deallocation. mUnionArrayPointer = safeConstantUnion; } @@ -345,13 +360,17 @@ class TIntermConstantUnion : public TIntermTyped void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; } - TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink); - TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink); - TConstantUnion *foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink); + TConstantUnion *foldBinary(TOperator op, + TIntermConstantUnion *rightNode, + TDiagnostics *diagnostics, + const TSourceLoc &line); + const TConstantUnion *foldIndexing(int index); + TConstantUnion *foldUnaryNonComponentWise(TOperator op); + TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics); - static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate, - TInfoSink &infoSink); - static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink); + static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate); + static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, + TDiagnostics *diagnostics); protected: // Same data may be shared between multiple constant unions, so it can't be modified. @@ -359,7 +378,9 @@ class TIntermConstantUnion : public TIntermTyped private: typedef float(*FloatTypeUnaryFunc) (float); - bool foldFloatTypeUnary(const TConstantUnion ¶meter, FloatTypeUnaryFunc builtinFunc, TInfoSink &infoSink, TConstantUnion *result) const; + void foldFloatTypeUnary(const TConstantUnion ¶meter, + FloatTypeUnaryFunc builtinFunc, + TConstantUnion *result) const; TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private! }; @@ -371,7 +392,6 @@ class TIntermOperator : public TIntermTyped { public: TOperator getOp() const { return mOp; } - void setOp(TOperator op) { mOp = op; } bool isAssignment() const; bool isMultiplication() const; @@ -392,18 +412,52 @@ class TIntermOperator : public TIntermTyped TOperator mOp; }; +// Node for vector swizzles. +class TIntermSwizzle : public TIntermTyped +{ + public: + // This constructor determines the type of the node based on the operand. + TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets); + + TIntermTyped *deepCopy() const override { return new TIntermSwizzle(*this); } + + TIntermSwizzle *getAsSwizzleNode() override { return this; }; + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + bool hasSideEffects() const override { return mOperand->hasSideEffects(); } + + TIntermTyped *getOperand() { return mOperand; } + void writeOffsetsAsXYZW(TInfoSinkBase *out) const; + + bool hasDuplicateOffsets() const; + + TIntermTyped *fold(); + + protected: + TIntermTyped *mOperand; + TVector<int> mSwizzleOffsets; + + private: + void promote(); + + TIntermSwizzle(const TIntermSwizzle &node); // Note: not deleted, just private! +}; + // // Nodes for all the basic binary math operators. // class TIntermBinary : public TIntermOperator { public: - TIntermBinary(TOperator op) - : TIntermOperator(op), - mAddIndexClamp(false) {} + // This constructor determines the type of the binary node based on the operands and op. + TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right); TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); } + static TOperator GetMulOpBasedOnOperands(const TType &left, const TType &right); + static TOperator GetMulAssignOpBasedOnOperands(const TType &left, const TType &right); + TIntermBinary *getAsBinaryNode() override { return this; }; void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; @@ -413,12 +467,9 @@ class TIntermBinary : public TIntermOperator return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects(); } - void setLeft(TIntermTyped *node) { mLeft = node; } - void setRight(TIntermTyped *node) { mRight = node; } TIntermTyped *getLeft() const { return mLeft; } TIntermTyped *getRight() const { return mRight; } - bool promote(TInfoSink &); - TIntermTyped *fold(TInfoSink &infoSink); + TIntermTyped *fold(TDiagnostics *diagnostics); void setAddIndexClamp() { mAddIndexClamp = true; } bool getAddIndexClamp() { return mAddIndexClamp; } @@ -431,6 +482,8 @@ class TIntermBinary : public TIntermOperator bool mAddIndexClamp; private: + void promote(); + TIntermBinary(const TIntermBinary &node); // Note: not deleted, just private! }; @@ -440,14 +493,7 @@ class TIntermBinary : public TIntermOperator class TIntermUnary : public TIntermOperator { public: - TIntermUnary(TOperator op, const TType &type) - : TIntermOperator(op, type), - mOperand(NULL), - mUseEmulatedFunction(false) {} - TIntermUnary(TOperator op) - : TIntermOperator(op), - mOperand(NULL), - mUseEmulatedFunction(false) {} + TIntermUnary(TOperator op, TIntermTyped *operand); TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); } @@ -457,10 +503,8 @@ class TIntermUnary : public TIntermOperator bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); } - void setOperand(TIntermTyped *operand) { mOperand = operand; } TIntermTyped *getOperand() { return mOperand; } - void promote(const TType *funcReturnType); - TIntermTyped *fold(TInfoSink &infoSink); + TIntermTyped *fold(TDiagnostics *diagnostics); void setUseEmulatedFunction() { mUseEmulatedFunction = true; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; } @@ -473,6 +517,8 @@ class TIntermUnary : public TIntermOperator bool mUseEmulatedFunction; private: + void promote(); + TIntermUnary(const TIntermUnary &node); // note: not deleted, just private! }; @@ -506,6 +552,8 @@ class TIntermAggregate : public TIntermOperator // Note: only supported for nodes that can be a part of an expression. TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); } + void setOp(TOperator op) { mOp = op; } + TIntermAggregate *getAsAggregate() override { return this; } void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; @@ -513,9 +561,10 @@ class TIntermAggregate : public TIntermOperator bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions); // Conservatively assume function calls and other aggregate operators have side-effects bool hasSideEffects() const override { return true; } - TIntermTyped *fold(TInfoSink &infoSink); + TIntermTyped *fold(TDiagnostics *diagnostics); TIntermSequence *getSequence() { return &mSequence; } + const TIntermSequence *getSequence() const { return &mSequence; } void setNameObj(const TName &name) { mName = name; } const TName &getNameObj() const { return mName; } @@ -555,46 +604,60 @@ class TIntermAggregate : public TIntermOperator TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private! }; -// -// For if tests. -// -class TIntermSelection : public TIntermTyped +// For ternary operators like a ? b : c. +class TIntermTernary : public TIntermTyped { public: - TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB) - : TIntermTyped(TType(EbtVoid, EbpUndefined)), - mCondition(cond), - mTrueBlock(trueB), - mFalseBlock(falseB) {} - TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB, - const TType &type) - : TIntermTyped(type), - mCondition(cond), - mTrueBlock(trueB), - mFalseBlock(falseB) {} - - // Note: only supported for ternary operator nodes. - TIntermTyped *deepCopy() const override { return new TIntermSelection(*this); } + TIntermTernary(TIntermTyped *cond, TIntermTyped *trueExpression, TIntermTyped *falseExpression); void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; - // Conservatively assume selections have side-effects - bool hasSideEffects() const override { return true; } + TIntermTyped *getCondition() const { return mCondition; } + TIntermTyped *getTrueExpression() const { return mTrueExpression; } + TIntermTyped *getFalseExpression() const { return mFalseExpression; } + TIntermTernary *getAsTernaryNode() override { return this; } - bool usesTernaryOperator() const { return getBasicType() != EbtVoid; } - TIntermNode *getCondition() const { return mCondition; } - TIntermNode *getTrueBlock() const { return mTrueBlock; } - TIntermNode *getFalseBlock() const { return mFalseBlock; } - TIntermSelection *getAsSelectionNode() override { return this; } + TIntermTyped *deepCopy() const override { return new TIntermTernary(*this); } - protected: - TIntermTyped *mCondition; - TIntermNode *mTrueBlock; - TIntermNode *mFalseBlock; + bool hasSideEffects() const override + { + return mCondition->hasSideEffects() || mTrueExpression->hasSideEffects() || + mFalseExpression->hasSideEffects(); + } + + static TQualifier DetermineQualifier(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression); private: - TIntermSelection(const TIntermSelection &node); // Note: not deleted, just private! + TIntermTernary(const TIntermTernary &node); // Note: not deleted, just private! + + TIntermTyped *mCondition; + TIntermTyped *mTrueExpression; + TIntermTyped *mFalseExpression; +}; + +class TIntermIfElse : public TIntermNode +{ + public: + TIntermIfElse(TIntermTyped *cond, TIntermAggregate *trueB, TIntermAggregate *falseB) + : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB) + { + } + + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + TIntermTyped *getCondition() const { return mCondition; } + TIntermAggregate *getTrueBlock() const { return mTrueBlock; } + TIntermAggregate *getFalseBlock() const { return mFalseBlock; } + TIntermIfElse *getAsIfElseNode() override { return this; } + + protected: + TIntermTyped *mCondition; + TIntermAggregate *mTrueBlock; + TIntermAggregate *mFalseBlock; }; // @@ -672,24 +735,17 @@ class TIntermTraverser : angle::NonCopyable { public: POOL_ALLOCATOR_NEW_DELETE(); - TIntermTraverser(bool preVisit, bool inVisit, bool postVisit) - : preVisit(preVisit), - inVisit(inVisit), - postVisit(postVisit), - mDepth(0), - mMaxDepth(0), - mInGlobalScope(true), - mTemporaryIndex(nullptr) - { - } - virtual ~TIntermTraverser() {} + TIntermTraverser(bool preVisit, bool inVisit, bool postVisit); + virtual ~TIntermTraverser(); virtual void visitSymbol(TIntermSymbol *node) {} virtual void visitRaw(TIntermRaw *node) {} virtual void visitConstantUnion(TIntermConstantUnion *node) {} + virtual bool visitSwizzle(Visit visit, TIntermSwizzle *node) { return true; } virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; } virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; } - virtual bool visitSelection(Visit visit, TIntermSelection *node) { return true; } + virtual bool visitTernary(Visit visit, TIntermTernary *node) { return true; } + virtual bool visitIfElse(Visit visit, TIntermIfElse *node) { return true; } virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; } virtual bool visitCase(Visit visit, TIntermCase *node) { return true; } virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; } @@ -702,9 +758,11 @@ class TIntermTraverser : angle::NonCopyable virtual void traverseSymbol(TIntermSymbol *node); virtual void traverseRaw(TIntermRaw *node); virtual void traverseConstantUnion(TIntermConstantUnion *node); + virtual void traverseSwizzle(TIntermSwizzle *node); virtual void traverseBinary(TIntermBinary *node); virtual void traverseUnary(TIntermUnary *node); - virtual void traverseSelection(TIntermSelection *node); + virtual void traverseTernary(TIntermTernary *node); + virtual void traverseIfElse(TIntermIfElse *node); virtual void traverseSwitch(TIntermSwitch *node); virtual void traverseCase(TIntermCase *node); virtual void traverseAggregate(TIntermAggregate *node); @@ -763,36 +821,6 @@ class TIntermTraverser : angle::NonCopyable return !mParentBlockStack.empty() && getParentNode() == mParentBlockStack.back().node; } - const bool preVisit; - const bool inVisit; - const bool postVisit; - - int mDepth; - int mMaxDepth; - - // All the nodes from root to the current node's parent during traversing. - TVector<TIntermNode *> mPath; - - bool mInGlobalScope; - - // To replace a single node with another on the parent node - struct NodeUpdateEntry - { - NodeUpdateEntry(TIntermNode *_parent, - TIntermNode *_original, - TIntermNode *_replacement, - bool _originalBecomesChildOfReplacement) - : parent(_parent), - original(_original), - replacement(_replacement), - originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement) {} - - TIntermNode *parent; - TIntermNode *original; - TIntermNode *replacement; - bool originalBecomesChildOfReplacement; - }; - // To replace a single node with multiple nodes on the parent aggregate node struct NodeReplaceWithMultipleEntry { @@ -828,13 +856,6 @@ class TIntermTraverser : angle::NonCopyable TIntermSequence insertionsAfter; }; - // During traversing, save all the changes that need to happen into - // mReplacements/mMultiReplacements, then do them by calling updateTree(). - // Multi replacements are processed after single replacements. - std::vector<NodeUpdateEntry> mReplacements; - std::vector<NodeReplaceWithMultipleEntry> mMultiReplacements; - std::vector<NodeInsertMultipleEntry> mInsertions; - // Helper to insert statements in the parent block (sequence) of the node currently being traversed. // The statements will be inserted before the node being traversed once updateTree is called. // Should only be called during PreVisit or PostVisit from sequence nodes. @@ -847,6 +868,9 @@ class TIntermTraverser : angle::NonCopyable void insertStatementsInParentBlock(const TIntermSequence &insertionsBefore, const TIntermSequence &insertionsAfter); + // Helper to insert a single statement. + void insertStatementInParentBlock(TIntermNode *statement); + // Helper to create a temporary symbol node with the given qualifier. TIntermSymbol *createTempSymbol(const TType &type, TQualifier qualifier); // Helper to create a temporary symbol node. @@ -862,7 +886,60 @@ class TIntermTraverser : angle::NonCopyable // Increment temporary symbol index. void nextTemporaryIndex(); + enum class OriginalNode + { + BECOMES_CHILD, + IS_DROPPED + }; + + void clearReplacementQueue(); + void queueReplacement(TIntermNode *original, + TIntermNode *replacement, + OriginalNode originalStatus); + void queueReplacementWithParent(TIntermNode *parent, + TIntermNode *original, + TIntermNode *replacement, + OriginalNode originalStatus); + + const bool preVisit; + const bool inVisit; + const bool postVisit; + + int mDepth; + int mMaxDepth; + + // All the nodes from root to the current node's parent during traversing. + TVector<TIntermNode *> mPath; + + bool mInGlobalScope; + + // During traversing, save all the changes that need to happen into + // mReplacements/mMultiReplacements, then do them by calling updateTree(). + // Multi replacements are processed after single replacements. + std::vector<NodeReplaceWithMultipleEntry> mMultiReplacements; + std::vector<NodeInsertMultipleEntry> mInsertions; + private: + // To replace a single node with another on the parent node + struct NodeUpdateEntry + { + NodeUpdateEntry(TIntermNode *_parent, + TIntermNode *_original, + TIntermNode *_replacement, + bool _originalBecomesChildOfReplacement) + : parent(_parent), + original(_original), + replacement(_replacement), + originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement) + { + } + + TIntermNode *parent; + TIntermNode *original; + TIntermNode *replacement; + bool originalBecomesChildOfReplacement; + }; + struct ParentBlock { ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn) @@ -874,6 +951,9 @@ class TIntermTraverser : angle::NonCopyable TIntermAggregate *node; TIntermSequence::size_type pos; }; + + std::vector<NodeUpdateEntry> mReplacements; + // All the code blocks from the root to the current node's parent during traversal. std::vector<ParentBlock> mParentBlockStack; @@ -899,9 +979,9 @@ class TLValueTrackingTraverser : public TIntermTraverser } virtual ~TLValueTrackingTraverser() {} - void traverseBinary(TIntermBinary *node) override; - void traverseUnary(TIntermUnary *node) override; - void traverseAggregate(TIntermAggregate *node) override; + void traverseBinary(TIntermBinary *node) final; + void traverseUnary(TIntermUnary *node) final; + void traverseAggregate(TIntermAggregate *node) final; protected: bool isLValueRequiredHere() const @@ -969,7 +1049,8 @@ class TMaxDepthTraverser : public TIntermTraverser bool visitBinary(Visit, TIntermBinary *) override { return depthCheck(); } bool visitUnary(Visit, TIntermUnary *) override { return depthCheck(); } - bool visitSelection(Visit, TIntermSelection *) override { return depthCheck(); } + bool visitTernary(Visit, TIntermTernary *) override { return depthCheck(); } + bool visitIfElse(Visit, TIntermIfElse *) override { return depthCheck(); } bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); } bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); } bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); } diff --git a/chromium/third_party/angle/src/compiler/translator/IntermNodePatternMatcher.cpp b/chromium/third_party/angle/src/compiler/translator/IntermNodePatternMatcher.cpp new file mode 100644 index 00000000000..63075635cf9 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/IntermNodePatternMatcher.cpp @@ -0,0 +1,115 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IntermNodePatternMatcher is a helper class for matching node trees to given patterns. +// It can be used whenever the same checks for certain node structures are common to multiple AST +// traversers. +// + +#include "compiler/translator/IntermNodePatternMatcher.h" + +#include "compiler/translator/IntermNode.h" + +namespace +{ + +bool IsNodeBlock(TIntermNode *node) +{ + ASSERT(node != nullptr); + return (node->getAsAggregate() && node->getAsAggregate()->getOp() == EOpSequence); +} + +} // anonymous namespace + +IntermNodePatternMatcher::IntermNodePatternMatcher(const unsigned int mask) : mMask(mask) +{ +} + +// static +bool IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node) +{ + return node->getOp() == EOpIndexIndirect && !node->getLeft()->isArray() && + node->getLeft()->getBasicType() != EbtStruct; +} + +bool IntermNodePatternMatcher::matchInternal(TIntermBinary *node, TIntermNode *parentNode) +{ + if ((mMask & kExpressionReturningArray) != 0) + { + if (node->isArray() && node->getOp() == EOpAssign && parentNode != nullptr && + !IsNodeBlock(parentNode)) + { + return true; + } + } + + if ((mMask & kUnfoldedShortCircuitExpression) != 0) + { + if (node->getRight()->hasSideEffects() && + (node->getOp() == EOpLogicalOr || node->getOp() == EOpLogicalAnd)) + { + return true; + } + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermBinary *node, TIntermNode *parentNode) +{ + // L-value tracking information is needed to check for dynamic indexing in L-value. + // Traversers that don't track l-values can still use this class and match binary nodes with + // this variation of this method if they don't need to check for dynamic indexing in l-values. + ASSERT((mMask & kDynamicIndexingOfVectorOrMatrixInLValue) == 0); + return matchInternal(node, parentNode); +} + +bool IntermNodePatternMatcher::match(TIntermBinary *node, + TIntermNode *parentNode, + bool isLValueRequiredHere) +{ + if (matchInternal(node, parentNode)) + { + return true; + } + if ((mMask & kDynamicIndexingOfVectorOrMatrixInLValue) != 0) + { + if (isLValueRequiredHere && IsDynamicIndexingOfVectorOrMatrix(node)) + { + return true; + } + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermAggregate *node, TIntermNode *parentNode) +{ + if ((mMask & kExpressionReturningArray) != 0) + { + if (parentNode != nullptr) + { + TIntermBinary *parentBinary = parentNode->getAsBinaryNode(); + bool parentIsAssignment = + (parentBinary != nullptr && + (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize)); + + if (node->getType().isArray() && !parentIsAssignment && + (node->isConstructor() || node->getOp() == EOpFunctionCall) && + !IsNodeBlock(parentNode)) + { + return true; + } + } + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermTernary *node) +{ + if ((mMask & kUnfoldedShortCircuitExpression) != 0) + { + return true; + } + return false; +} diff --git a/chromium/third_party/angle/src/compiler/translator/IntermNodePatternMatcher.h b/chromium/third_party/angle/src/compiler/translator/IntermNodePatternMatcher.h new file mode 100644 index 00000000000..3e24f8560e1 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/IntermNodePatternMatcher.h @@ -0,0 +1,53 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IntermNodePatternMatcher is a helper class for matching node trees to given patterns. +// It can be used whenever the same checks for certain node structures are common to multiple AST +// traversers. +// + +#ifndef COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_ +#define COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_ + +class TIntermAggregate; +class TIntermBinary; +class TIntermNode; +class TIntermTernary; + +class IntermNodePatternMatcher +{ + public: + static bool IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node); + + enum PatternType + { + // Matches expressions that are unfolded to if statements by UnfoldShortCircuitToIf + kUnfoldedShortCircuitExpression = 0x0001, + + // Matches expressions that return arrays with the exception of simple statements where a + // constructor or function call result is assigned. + kExpressionReturningArray = 0x0002, + + // Matches dynamic indexing of vectors or matrices in l-values. + kDynamicIndexingOfVectorOrMatrixInLValue = 0x0004 + }; + IntermNodePatternMatcher(const unsigned int mask); + + bool match(TIntermBinary *node, TIntermNode *parentNode); + + // Use this version for checking binary node matches in case you're using flag + // kDynamicIndexingOfVectorOrMatrixInLValue. + bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere); + + bool match(TIntermAggregate *node, TIntermNode *parentNode); + bool match(TIntermTernary *node); + + private: + const unsigned int mMask; + + bool matchInternal(TIntermBinary *node, TIntermNode *parentNode); +}; + +#endif diff --git a/chromium/third_party/angle/src/compiler/translator/IntermTraverse.cpp b/chromium/third_party/angle/src/compiler/translator/IntermTraverse.cpp index b785c40f14a..189a422d40a 100644 --- a/chromium/third_party/angle/src/compiler/translator/IntermTraverse.cpp +++ b/chromium/third_party/angle/src/compiler/translator/IntermTraverse.cpp @@ -23,6 +23,11 @@ void TIntermConstantUnion::traverse(TIntermTraverser *it) it->traverseConstantUnion(this); } +void TIntermSwizzle::traverse(TIntermTraverser *it) +{ + it->traverseSwizzle(this); +} + void TIntermBinary::traverse(TIntermTraverser *it) { it->traverseBinary(this); @@ -33,9 +38,14 @@ void TIntermUnary::traverse(TIntermTraverser *it) it->traverseUnary(this); } -void TIntermSelection::traverse(TIntermTraverser *it) +void TIntermTernary::traverse(TIntermTraverser *it) +{ + it->traverseTernary(this); +} + +void TIntermIfElse::traverse(TIntermTraverser *it) { - it->traverseSelection(this); + it->traverseIfElse(this); } void TIntermSwitch::traverse(TIntermTraverser *it) @@ -63,6 +73,21 @@ void TIntermBranch::traverse(TIntermTraverser *it) it->traverseBranch(this); } +TIntermTraverser::TIntermTraverser(bool preVisit, bool inVisit, bool postVisit) + : preVisit(preVisit), + inVisit(inVisit), + postVisit(postVisit), + mDepth(0), + mMaxDepth(0), + mInGlobalScope(true), + mTemporaryIndex(nullptr) +{ +} + +TIntermTraverser::~TIntermTraverser() +{ +} + void TIntermTraverser::pushParentBlock(TIntermAggregate *node) { mParentBlockStack.push_back(ParentBlock(node, 0)); @@ -94,6 +119,13 @@ void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &inse mInsertions.push_back(insert); } +void TIntermTraverser::insertStatementInParentBlock(TIntermNode *statement) +{ + TIntermSequence insertions; + insertions.push_back(statement); + insertStatementsInParentBlock(insertions); +} + TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type, TQualifier qualifier) { // Each traversal uses at most one temporary variable, so the index stays the same within a single traversal. @@ -125,10 +157,7 @@ TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *init ASSERT(initializer != nullptr); TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier); TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); - TIntermBinary *tempInit = new TIntermBinary(EOpInitialize); - tempInit->setLeft(tempSymbol); - tempInit->setRight(initializer); - tempInit->setType(tempSymbol->getType()); + TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer); tempDeclaration->getSequence()->push_back(tempInit); return tempDeclaration; } @@ -142,10 +171,7 @@ TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode) { ASSERT(rightNode != nullptr); TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType()); - TIntermBinary *assignment = new TIntermBinary(EOpAssign); - assignment->setLeft(tempSymbol); - assignment->setRight(rightNode); - assignment->setType(tempSymbol->getType()); + TIntermBinary *assignment = new TIntermBinary(EOpAssign, tempSymbol, rightNode); return assignment; } @@ -211,6 +237,26 @@ void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node) visitConstantUnion(node); } +void TIntermTraverser::traverseSwizzle(TIntermSwizzle *node) +{ + bool visit = true; + + if (preVisit) + visit = visitSwizzle(PreVisit, node); + + if (visit) + { + incrementDepth(node); + + node->getOperand()->traverse(this); + + decrementDepth(); + } + + if (visit && postVisit) + visitSwizzle(PostVisit, node); +} + // // Traverse a binary node. // @@ -551,14 +597,37 @@ void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node) } // -// Traverse a selection node. Same comments in binary node apply here. +// Traverse a ternary node. Same comments in binary node apply here. // -void TIntermTraverser::traverseSelection(TIntermSelection *node) +void TIntermTraverser::traverseTernary(TIntermTernary *node) +{ + bool visit = true; + + if (preVisit) + visit = visitTernary(PreVisit, node); + + if (visit) + { + incrementDepth(node); + node->getCondition()->traverse(this); + if (node->getTrueExpression()) + node->getTrueExpression()->traverse(this); + if (node->getFalseExpression()) + node->getFalseExpression()->traverse(this); + decrementDepth(); + } + + if (visit && postVisit) + visitTernary(PostVisit, node); +} + +// Traverse an if-else node. Same comments in binary node apply here. +void TIntermTraverser::traverseIfElse(TIntermIfElse *node) { bool visit = true; if (preVisit) - visit = visitSelection(PreVisit, node); + visit = visitIfElse(PreVisit, node); if (visit) { @@ -572,7 +641,7 @@ void TIntermTraverser::traverseSelection(TIntermSelection *node) } if (visit && postVisit) - visitSelection(PostVisit, node); + visitIfElse(PostVisit, node); } // diff --git a/chromium/third_party/angle/src/compiler/translator/Intermediate.cpp b/chromium/third_party/angle/src/compiler/translator/Intermediate.cpp index 0adb7212b76..57d53bf21ea 100644 --- a/chromium/third_party/angle/src/compiler/translator/Intermediate.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Intermediate.cpp @@ -38,99 +38,26 @@ TIntermSymbol *TIntermediate::addSymbol( } // -// Connect two nodes with a new parent that does a binary operation on the nodes. -// -// Returns the added node. -// -TIntermTyped *TIntermediate::addBinaryMath( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line) -{ - // - // Need a new node holding things together then. Make - // one and promote it to the right type. - // - TIntermBinary *node = new TIntermBinary(op); - node->setLine(line); - - node->setLeft(left); - node->setRight(right); - if (!node->promote(mInfoSink)) - return NULL; - - // See if we can fold constants. - TIntermTyped *foldedNode = node->fold(mInfoSink); - if (foldedNode) - return foldedNode; - - return node; -} - -// -// Connect two nodes through an assignment. -// -// Returns the added node. -// -TIntermTyped *TIntermediate::addAssign( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line) -{ - if (left->getType().getStruct() || right->getType().getStruct()) - { - if (left->getType() != right->getType()) - { - return NULL; - } - } - - TIntermBinary *node = new TIntermBinary(op); - node->setLine(line); - - node->setLeft(left); - node->setRight(right); - if (!node->promote(mInfoSink)) - return NULL; - - return node; -} - -// // Connect two nodes through an index operator, where the left node is the base // of an array or struct, and the right node is a direct or indirect offset. // // Returns the added node. // The caller should set the type of the returned node. // -TIntermTyped *TIntermediate::addIndex( - TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &line) -{ - TIntermBinary *node = new TIntermBinary(op); - node->setLine(line); - node->setLeft(base); - node->setRight(index); - - // caller should set the type - - return node; -} - -// -// Add one node as the parent of another that it operates on. -// -// Returns the added node. -// -TIntermTyped *TIntermediate::addUnaryMath( - TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType) +TIntermTyped *TIntermediate::addIndex(TOperator op, + TIntermTyped *base, + TIntermTyped *index, + const TSourceLoc &line, + TDiagnostics *diagnostics) { - // - // Make a new node for the operator. - // - TIntermUnary *node = new TIntermUnary(op); + TIntermBinary *node = new TIntermBinary(op, base, index); node->setLine(line); - node->setOperand(child); - node->promote(funcReturnType); - TIntermTyped *foldedNode = node->fold(mInfoSink); - if (foldedNode) - return foldedNode; + TIntermTyped *folded = node->fold(diagnostics); + if (folded) + { + return folded; + } return node; } @@ -215,11 +142,10 @@ TIntermAggregate *TIntermediate::growAggregate( // // Returns an aggregate, unless NULL was passed in for the existing node. // -TIntermAggregate *TIntermediate::makeAggregate( - TIntermNode *node, const TSourceLoc &line) +TIntermAggregate *TIntermediate::MakeAggregate(TIntermNode *node, const TSourceLoc &line) { - if (node == NULL) - return NULL; + if (node == nullptr) + return nullptr; TIntermAggregate *aggNode = new TIntermAggregate; aggNode->getSequence()->push_back(node); @@ -232,7 +158,7 @@ TIntermAggregate *TIntermediate::makeAggregate( // If the input node is nullptr, return nullptr. // If the input node is a sequence (block) node, return it. // If the input node is not a sequence node, put it inside a sequence node and return that. -TIntermAggregate *TIntermediate::ensureSequence(TIntermNode *node) +TIntermAggregate *TIntermediate::EnsureSequence(TIntermNode *node) { if (node == nullptr) return nullptr; @@ -240,42 +166,40 @@ TIntermAggregate *TIntermediate::ensureSequence(TIntermNode *node) if (aggNode != nullptr && aggNode->getOp() == EOpSequence) return aggNode; - aggNode = makeAggregate(node, node->getLine()); + aggNode = MakeAggregate(node, node->getLine()); aggNode->setOp(EOpSequence); return aggNode; } -// // For "if" test nodes. There are three children; a condition, // a true path, and a false path. The two paths are in the // nodePair. // -// Returns the selection node created. -// -TIntermNode *TIntermediate::addSelection( - TIntermTyped *cond, TIntermNodePair nodePair, const TSourceLoc &line) +// Returns the node created. +TIntermNode *TIntermediate::addIfElse(TIntermTyped *cond, + TIntermNodePair nodePair, + const TSourceLoc &line) { - // - // For compile time constant selections, prune the code and - // test now. - // + // For compile time constant conditions, prune the code now. if (cond->getAsConstantUnion()) { if (cond->getAsConstantUnion()->getBConst(0) == true) { - return nodePair.node1 ? setAggregateOperator( - nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL; + return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, + nodePair.node1->getLine()) + : nullptr; } else { - return nodePair.node2 ? setAggregateOperator( - nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL; + return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, + nodePair.node2->getLine()) + : nullptr; } } - TIntermSelection *node = new TIntermSelection( - cond, ensureSequence(nodePair.node1), ensureSequence(nodePair.node2)); + TIntermIfElse *node = + new TIntermIfElse(cond, EnsureSequence(nodePair.node1), EnsureSequence(nodePair.node2)); node->setLine(line); return node; @@ -309,43 +233,37 @@ TIntermTyped *TIntermediate::addComma(TIntermTyped *left, return commaNode; } -// // For "?:" test nodes. There are three children; a condition, // a true path, and a false path. The two paths are specified // as separate parameters. // -// Returns the selection node created, or one of trueBlock and falseBlock if the expression could be folded. -// -TIntermTyped *TIntermediate::addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, - const TSourceLoc &line) +// Returns the ternary node created, or one of trueExpression and falseExpression if the expression +// could be folded. +TIntermTyped *TIntermediate::AddTernarySelection(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression, + const TSourceLoc &line) { - TQualifier resultQualifier = EvqTemporary; - if (cond->getQualifier() == EvqConst && trueBlock->getQualifier() == EvqConst && - falseBlock->getQualifier() == EvqConst) - { - resultQualifier = EvqConst; - } // Note that the node resulting from here can be a constant union without being qualified as // constant. if (cond->getAsConstantUnion()) { + TQualifier resultQualifier = + TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression); if (cond->getAsConstantUnion()->getBConst(0)) { - trueBlock->getTypePointer()->setQualifier(resultQualifier); - return trueBlock; + trueExpression->getTypePointer()->setQualifier(resultQualifier); + return trueExpression; } else { - falseBlock->getTypePointer()->setQualifier(resultQualifier); - return falseBlock; + falseExpression->getTypePointer()->setQualifier(resultQualifier); + return falseExpression; } } - // - // Make a selection node. - // - TIntermSelection *node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); - node->getTypePointer()->setQualifier(resultQualifier); + // Make a ternary node. + TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression); node->setLine(line); return node; @@ -385,24 +303,22 @@ TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *cons return node; } -TIntermTyped *TIntermediate::addSwizzle( - TVectorFields &fields, const TSourceLoc &line) +TIntermTyped *TIntermediate::AddSwizzle(TIntermTyped *baseExpression, + const TVectorFields &fields, + const TSourceLoc &dotLocation) { + TVector<int> fieldsVector; + for (int i = 0; i < fields.num; ++i) + { + fieldsVector.push_back(fields.offsets[i]); + } + TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldsVector); + node->setLine(dotLocation); - TIntermAggregate *node = new TIntermAggregate(EOpSequence); - - node->setLine(line); - TIntermConstantUnion *constIntNode; - TIntermSequence *sequenceVector = node->getSequence(); - TConstantUnion *unionArray; - - for (int i = 0; i < fields.num; i++) + TIntermTyped *folded = node->fold(); + if (folded) { - unionArray = new TConstantUnion[1]; - unionArray->setIConst(fields.offsets[i]); - constIntNode = addConstantUnion( - unionArray, TType(EbtInt, EbpUndefined, EvqConst), line); - sequenceVector->push_back(constIntNode); + return folded; } return node; @@ -415,7 +331,7 @@ TIntermNode *TIntermediate::addLoop( TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr, TIntermNode *body, const TSourceLoc &line) { - TIntermNode *node = new TIntermLoop(type, init, cond, expr, ensureSequence(body)); + TIntermNode *node = new TIntermLoop(type, init, cond, expr, EnsureSequence(body)); node->setLine(line); return node; @@ -443,7 +359,7 @@ TIntermBranch* TIntermediate::addBranch( // This is to be executed once the final root is put on top by the parsing // process. // -TIntermAggregate *TIntermediate::postProcess(TIntermNode *root) +TIntermAggregate *TIntermediate::PostProcess(TIntermNode *root) { if (root == nullptr) return nullptr; @@ -466,7 +382,8 @@ TIntermAggregate *TIntermediate::postProcess(TIntermNode *root) return aggRoot; } -TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate) +TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate, + TDiagnostics *diagnostics) { switch (aggregate->getOp()) { @@ -493,16 +410,14 @@ TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate) case EOpFaceForward: case EOpReflect: case EOpRefract: - return aggregate->fold(mInfoSink); + return aggregate->fold(diagnostics); default: // TODO: Add support for folding array constructors if (aggregate->isConstructor() && !aggregate->isArray()) { - return aggregate->fold(mInfoSink); + return aggregate->fold(diagnostics); } // Constant folding not supported for the built-in. return nullptr; } - - return nullptr; } diff --git a/chromium/third_party/angle/src/compiler/translator/Intermediate.h b/chromium/third_party/angle/src/compiler/translator/Intermediate.h index f723fc76481..c4a21d84bb3 100644 --- a/chromium/third_party/angle/src/compiler/translator/Intermediate.h +++ b/chromium/third_party/angle/src/compiler/translator/Intermediate.h @@ -16,34 +16,33 @@ struct TVectorFields }; // -// Set of helper functions to help parse and build the tree. +// Set of helper functions to help build the tree. // -class TInfoSink; class TIntermediate { public: POOL_ALLOCATOR_NEW_DELETE(); - TIntermediate(TInfoSink &i) - : mInfoSink(i) { } + TIntermediate() {} TIntermSymbol *addSymbol( int id, const TString &, const TType &, const TSourceLoc &); - TIntermTyped *addBinaryMath( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &); - TIntermTyped *addAssign( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &); - TIntermTyped *addIndex( - TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &); + TIntermTyped *addIndex(TOperator op, + TIntermTyped *base, + TIntermTyped *index, + const TSourceLoc &line, + TDiagnostics *diagnostics); TIntermTyped *addUnaryMath( TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType); TIntermAggregate *growAggregate( TIntermNode *left, TIntermNode *right, const TSourceLoc &); - TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &); - TIntermAggregate *ensureSequence(TIntermNode *node); + static TIntermAggregate *MakeAggregate(TIntermNode *node, const TSourceLoc &line); + static TIntermAggregate *EnsureSequence(TIntermNode *node); TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &); - TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &); - TIntermTyped *addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, - const TSourceLoc &line); + TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &line); + static TIntermTyped *AddTernarySelection(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression, + const TSourceLoc &line); TIntermSwitch *addSwitch( TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line); TIntermCase *addCase( @@ -59,17 +58,17 @@ class TIntermediate TIntermNode *, const TSourceLoc &); TIntermBranch *addBranch(TOperator, const TSourceLoc &); TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &); - TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &); - TIntermAggregate *postProcess(TIntermNode *root); + static TIntermTyped *AddSwizzle(TIntermTyped *baseExpression, + const TVectorFields &fields, + const TSourceLoc &dotLocation); + static TIntermAggregate *PostProcess(TIntermNode *root); static void outputTree(TIntermNode *, TInfoSinkBase &); - TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate); + TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate, TDiagnostics *diagnostics); private: void operator=(TIntermediate &); // prevent assignments - - TInfoSink & mInfoSink; }; #endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/Operator.cpp b/chromium/third_party/angle/src/compiler/translator/Operator.cpp index 20e47f290e1..57878b93017 100644 --- a/chromium/third_party/angle/src/compiler/translator/Operator.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Operator.cpp @@ -62,8 +62,6 @@ const char *GetOperatorString(TOperator op) case EOpIndexDirectStruct: case EOpIndexDirectInterfaceBlock: return "."; - case EOpVectorSwizzle: return "."; - case EOpRadians: return "radians"; case EOpDegrees: return "degrees"; case EOpSin: return "sin"; @@ -199,3 +197,31 @@ const char *GetOperatorString(TOperator op) return ""; } +bool IsAssignment(TOperator op) +{ + switch (op) + { + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + case EOpAssign: + case EOpAddAssign: + case EOpSubAssign: + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + case EOpDivAssign: + case EOpIModAssign: + case EOpBitShiftLeftAssign: + case EOpBitShiftRightAssign: + case EOpBitwiseAndAssign: + case EOpBitwiseXorAssign: + case EOpBitwiseOrAssign: + return true; + default: + return false; + } +}
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/translator/Operator.h b/chromium/third_party/angle/src/compiler/translator/Operator.h index b0efb8f48bd..479372111ef 100644 --- a/chromium/third_party/angle/src/compiler/translator/Operator.h +++ b/chromium/third_party/angle/src/compiler/translator/Operator.h @@ -77,8 +77,6 @@ enum TOperator EOpIndexDirectStruct, EOpIndexDirectInterfaceBlock, - EOpVectorSwizzle, - // // Built-in functions potentially mapped to operators // @@ -228,4 +226,7 @@ enum TOperator // Returns the string corresponding to the operator in GLSL const char* GetOperatorString(TOperator op); +// Say whether or not a binary or unary operation changes the value of a variable. +bool IsAssignment(TOperator op); + #endif // COMPILER_TRANSLATOR_OPERATOR_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.cpp b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.cpp index f048b050b7e..32db9de24f0 100644 --- a/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.cpp +++ b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.cpp @@ -27,11 +27,9 @@ bool isSingleStatement(TIntermNode *node) return (aggregate->getOp() != EOpFunction) && (aggregate->getOp() != EOpSequence); } - else if (const TIntermSelection *selection = node->getAsSelectionNode()) + else if (node->getAsIfElseNode()) { - // Ternary operators are usually part of an assignment operator. - // This handles those rare cases in which they are all by themselves. - return selection->usesTernaryOperator(); + return false; } else if (node->getAsLoopNode()) { @@ -243,20 +241,20 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion( return pConstUnion; } -void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type, const char *constructorBaseType) +void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type) { TInfoSinkBase &out = objSink(); if (visit == PreVisit) { if (type.isArray()) { - out << constructorBaseType; + out << getTypeName(type); out << arrayBrackets(type); out << "("; } else { - out << constructorBaseType << "("; + out << getTypeName(type) << "("; } } else @@ -282,6 +280,17 @@ void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node) writeConstantUnion(node->getType(), node->getUnionArrayPointer()); } +bool TOutputGLSLBase::visitSwizzle(Visit visit, TIntermSwizzle *node) +{ + TInfoSinkBase &out = objSink(); + if (visit == PostVisit) + { + out << "."; + node->writeOffsetsAsXYZW(&out); + } + return true; +} + bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) { bool visitChildren = true; @@ -357,7 +366,7 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) if (left->isArray()) { // The shader will fail validation if the array length is not > 0. - maxSize = leftType.getArraySize() - 1; + maxSize = static_cast<int>(leftType.getArraySize()) - 1; } else { @@ -412,40 +421,6 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) visitChildren = false; } break; - case EOpVectorSwizzle: - if (visit == InVisit) - { - out << "."; - TIntermAggregate *rightChild = node->getRight()->getAsAggregate(); - TIntermSequence *sequence = rightChild->getSequence(); - for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); ++sit) - { - TIntermConstantUnion *element = (*sit)->getAsConstantUnion(); - ASSERT(element->getBasicType() == EbtInt); - ASSERT(element->getNominalSize() == 1); - const TConstantUnion& data = element->getUnionArrayPointer()[0]; - ASSERT(data.getType() == EbtInt); - switch (data.getIConst()) - { - case 0: - out << "x"; - break; - case 1: - out << "y"; - break; - case 2: - out << "z"; - break; - case 3: - out << "w"; - break; - default: - UNREACHABLE(); - } - } - visitChildren = false; - } - break; case EOpAdd: writeTriplet(visit, "(", " + ", ")"); @@ -711,40 +686,40 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node) return true; } -bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node) +bool TOutputGLSLBase::visitTernary(Visit visit, TIntermTernary *node) { TInfoSinkBase &out = objSink(); + // Notice two brackets at the beginning and end. The outer ones + // encapsulate the whole ternary expression. This preserves the + // order of precedence when ternary expressions are used in a + // compound expression, i.e., c = 2 * (a < b ? 1 : 2). + out << "(("; + node->getCondition()->traverse(this); + out << ") ? ("; + node->getTrueExpression()->traverse(this); + out << ") : ("; + node->getFalseExpression()->traverse(this); + out << "))"; + return false; +} - if (node->usesTernaryOperator()) - { - // Notice two brackets at the beginning and end. The outer ones - // encapsulate the whole ternary expression. This preserves the - // order of precedence when ternary expressions are used in a - // compound expression, i.e., c = 2 * (a < b ? 1 : 2). - out << "(("; - node->getCondition()->traverse(this); - out << ") ? ("; - node->getTrueBlock()->traverse(this); - out << ") : ("; - node->getFalseBlock()->traverse(this); - out << "))"; - } - else - { - out << "if ("; - node->getCondition()->traverse(this); - out << ")\n"; +bool TOutputGLSLBase::visitIfElse(Visit visit, TIntermIfElse *node) +{ + TInfoSinkBase &out = objSink(); - incrementDepth(node); - visitCodeBlock(node->getTrueBlock()); + out << "if ("; + node->getCondition()->traverse(this); + out << ")\n"; - if (node->getFalseBlock()) - { - out << "else\n"; - visitCodeBlock(node->getFalseBlock()); - } - decrementDepth(); + incrementDepth(node); + visitCodeBlock(node->getTrueBlock()); + + if (node->getFalseBlock()) + { + out << "else\n"; + visitCodeBlock(node->getFalseBlock()); } + decrementDepth(); return false; } @@ -843,22 +818,19 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) out << " " << hashFunctionNameIfNeeded(node->getNameObj()); incrementDepth(node); - // Function definition node contains one or two children nodes - // representing function parameters and function body. The latter - // is not present in case of empty function bodies. + // Function definition node contains two child nodes representing the function parameters + // and the function body. const TIntermSequence &sequence = *(node->getSequence()); - ASSERT((sequence.size() == 1) || (sequence.size() == 2)); - TIntermSequence::const_iterator seqIter = sequence.begin(); + ASSERT(sequence.size() == 2); // Traverse function parameters. - TIntermAggregate *params = (*seqIter)->getAsAggregate(); + TIntermAggregate *params = sequence[0]->getAsAggregate(); ASSERT(params != NULL); ASSERT(params->getOp() == EOpParameters); params->traverse(this); // Traverse function body. - TIntermAggregate *body = ++seqIter != sequence.end() ? - (*seqIter)->getAsAggregate() : NULL; + TIntermAggregate *body = sequence[1]->getAsAggregate(); visitCodeBlock(body); decrementDepth(); @@ -917,88 +889,33 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) visitChildren = false; break; case EOpConstructFloat: - writeConstructorTriplet(visit, node->getType(), "float"); - break; case EOpConstructVec2: - writeConstructorTriplet(visit, node->getType(), "vec2"); - break; case EOpConstructVec3: - writeConstructorTriplet(visit, node->getType(), "vec3"); - break; case EOpConstructVec4: - writeConstructorTriplet(visit, node->getType(), "vec4"); - break; case EOpConstructBool: - writeConstructorTriplet(visit, node->getType(), "bool"); - break; case EOpConstructBVec2: - writeConstructorTriplet(visit, node->getType(), "bvec2"); - break; case EOpConstructBVec3: - writeConstructorTriplet(visit, node->getType(), "bvec3"); - break; case EOpConstructBVec4: - writeConstructorTriplet(visit, node->getType(), "bvec4"); - break; case EOpConstructInt: - writeConstructorTriplet(visit, node->getType(), "int"); - break; case EOpConstructIVec2: - writeConstructorTriplet(visit, node->getType(), "ivec2"); - break; case EOpConstructIVec3: - writeConstructorTriplet(visit, node->getType(), "ivec3"); - break; case EOpConstructIVec4: - writeConstructorTriplet(visit, node->getType(), "ivec4"); - break; case EOpConstructUInt: - writeConstructorTriplet(visit, node->getType(), "uint"); - break; case EOpConstructUVec2: - writeConstructorTriplet(visit, node->getType(), "uvec2"); - break; case EOpConstructUVec3: - writeConstructorTriplet(visit, node->getType(), "uvec3"); - break; case EOpConstructUVec4: - writeConstructorTriplet(visit, node->getType(), "uvec4"); - break; case EOpConstructMat2: - writeConstructorTriplet(visit, node->getType(), "mat2"); - break; case EOpConstructMat2x3: - writeConstructorTriplet(visit, node->getType(), "mat2x3"); - break; case EOpConstructMat2x4: - writeConstructorTriplet(visit, node->getType(), "mat2x4"); - break; case EOpConstructMat3x2: - writeConstructorTriplet(visit, node->getType(), "mat3x2"); - break; case EOpConstructMat3: - writeConstructorTriplet(visit, node->getType(), "mat3"); - break; case EOpConstructMat3x4: - writeConstructorTriplet(visit, node->getType(), "mat3x4"); - break; case EOpConstructMat4x2: - writeConstructorTriplet(visit, node->getType(), "mat4x2"); - break; case EOpConstructMat4x3: - writeConstructorTriplet(visit, node->getType(), "mat4x3"); - break; case EOpConstructMat4: - writeConstructorTriplet(visit, node->getType(), "mat4"); - break; case EOpConstructStruct: - { - const TType &type = node->getType(); - ASSERT(type.getBasicType() == EbtStruct); - TString constructorName = hashName(type.getStruct()->name()); - writeConstructorTriplet(visit, node->getType(), constructorName.c_str()); - break; - } + writeConstructorTriplet(visit, node->getType()); + break; case EOpOuterProduct: writeBuiltInFunctionTriplet(visit, "outerProduct(", useEmulatedFunction); @@ -1208,45 +1125,10 @@ void TOutputGLSLBase::visitCodeBlock(TIntermNode *node) TString TOutputGLSLBase::getTypeName(const TType &type) { - TInfoSinkBase out; - if (type.isMatrix()) - { - out << "mat"; - out << type.getNominalSize(); - if (type.getSecondarySize() != type.getNominalSize()) - { - out << "x" << type.getSecondarySize(); - } - } - else if (type.isVector()) - { - switch (type.getBasicType()) - { - case EbtFloat: - out << "vec"; - break; - case EbtInt: - out << "ivec"; - break; - case EbtBool: - out << "bvec"; - break; - case EbtUInt: - out << "uvec"; - break; - default: - UNREACHABLE(); - } - out << type.getNominalSize(); - } + if (type.getBasicType() == EbtStruct) + return hashName(type.getStruct()->name()); else - { - if (type.getBasicType() == EbtStruct) - out << hashName(type.getStruct()->name()); - else - out << type.getBasicString(); - } - return TString(out.c_str()); + return type.getBuiltInTypeNameString(); } TString TOutputGLSLBase::hashName(const TString &name) diff --git a/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.h b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.h index 2ae82d15b21..f8df0cd0275 100644 --- a/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.h +++ b/chromium/third_party/angle/src/compiler/translator/OutputGLSLBase.h @@ -37,14 +37,16 @@ class TOutputGLSLBase : public TIntermTraverser virtual bool writeVariablePrecision(TPrecision precision) = 0; void writeFunctionParameters(const TIntermSequence &args); const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *pConstUnion); - void writeConstructorTriplet(Visit visit, const TType &type, const char *constructorBaseType); + void writeConstructorTriplet(Visit visit, const TType &type); TString getTypeName(const TType &type); void visitSymbol(TIntermSymbol *node) override; void visitConstantUnion(TIntermConstantUnion *node) override; + bool visitSwizzle(Visit visit, TIntermSwizzle *node) override; bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitUnary(Visit visit, TIntermUnary *node) override; - bool visitSelection(Visit visit, TIntermSelection *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + bool visitIfElse(Visit visit, TIntermIfElse *node) override; bool visitSwitch(Visit visit, TIntermSwitch *node) override; bool visitCase(Visit visit, TIntermCase *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override; diff --git a/chromium/third_party/angle/src/compiler/translator/OutputHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.cpp index 3badefd5a51..4ed4b42f562 100644 --- a/chromium/third_party/angle/src/compiler/translator/OutputHLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.cpp @@ -80,11 +80,14 @@ const TConstantUnion *WriteConstantUnionArray(TInfoSinkBase &out, namespace sh { -OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion, - const TExtensionBehavior &extensionBehavior, - const char *sourcePath, ShShaderOutput outputType, - int numRenderTargets, const std::vector<Uniform> &uniforms, - int compileOptions) +OutputHLSL::OutputHLSL(sh::GLenum shaderType, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + const char *sourcePath, + ShShaderOutput outputType, + int numRenderTargets, + const std::vector<Uniform> &uniforms, + ShCompileOptions compileOptions) : TIntermTraverser(true, true, true), mShaderType(shaderType), mShaderVersion(shaderVersion), @@ -158,6 +161,12 @@ void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink) BuiltInFunctionEmulator builtInFunctionEmulator; InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator); + if ((mCompileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION) != 0) + { + InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(&builtInFunctionEmulator, + mShaderVersion); + } + builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(treeRoot); // Now that we are done changing the AST, do the analyses need for HLSL generation @@ -224,7 +233,7 @@ const std::map<std::string, unsigned int> &OutputHLSL::getUniformRegisterMap() c int OutputHLSL::vectorSize(const TType &type) const { int elementSize = type.isMatrix() ? type.getCols() : 1; - int arraySize = type.isArray() ? type.getArraySize() : 1; + unsigned int arraySize = type.isArray() ? type.getArraySize() : 1u; return elementSize * arraySize; } @@ -605,7 +614,9 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built } } - mTextureFunctionHLSL->textureFunctionHeader(out, mOutputType); + bool getDimensionsIgnoresBaseLevel = + (mCompileOptions & SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL) != 0; + mTextureFunctionHLSL->textureFunctionHeader(out, mOutputType, getDimensionsIgnoresBaseLevel); if (mUsesFragCoord) { @@ -837,6 +848,17 @@ bool OutputHLSL::ancestorEvaluatesToSamplerInStruct(Visit visit) return false; } +bool OutputHLSL::visitSwizzle(Visit visit, TIntermSwizzle *node) +{ + TInfoSinkBase &out = getInfoSink(); + if (visit == PostVisit) + { + out << "."; + node->writeOffsetsAsXYZW(&out); + } + return true; +} + bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) { TInfoSinkBase &out = getInfoSink(); @@ -1055,42 +1077,6 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) return false; } break; - case EOpVectorSwizzle: - if (visit == InVisit) - { - out << "."; - - TIntermAggregate *swizzle = node->getRight()->getAsAggregate(); - - if (swizzle) - { - TIntermSequence *sequence = swizzle->getSequence(); - - for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++) - { - TIntermConstantUnion *element = (*sit)->getAsConstantUnion(); - - if (element) - { - int i = element->getIConst(0); - - switch (i) - { - case 0: out << "x"; break; - case 1: out << "y"; break; - case 2: out << "z"; break; - case 3: out << "w"; break; - default: UNREACHABLE(); - } - } - else UNREACHABLE(); - } - } - else UNREACHABLE(); - - return false; // Fully processed - } - break; case EOpAdd: outputTriplet(out, visit, "(", " + ", ")"); break; @@ -1294,9 +1280,12 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) outputTriplet(out, visit, "frac(", "", ")"); break; case EOpIsNan: - outputTriplet(out, visit, "isnan(", "", ")"); - mRequiresIEEEStrictCompiling = true; - break; + if (node->getUseEmulatedFunction()) + writeEmulatedFunctionTriplet(out, visit, "isnan("); + else + outputTriplet(out, visit, "isnan(", "", ")"); + mRequiresIEEEStrictCompiling = true; + break; case EOpIsInf: outputTriplet(out, visit, "isinf(", "", ")"); break; @@ -1452,11 +1441,10 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) // Don't output ; after case labels, they're terminated by : // This is needed especially since outputting a ; after a case statement would turn empty // case statements into non-empty case statements, disallowing fall-through from them. - // Also no need to output ; after selection (if) statements or sequences. This is done just - // for code clarity. - TIntermSelection *asSelection = (*sit)->getAsSelectionNode(); - ASSERT(asSelection == nullptr || !asSelection->usesTernaryOperator()); - if ((*sit)->getAsCaseNode() == nullptr && asSelection == nullptr && !IsSequence(*sit)) + // Also no need to output ; after if statements or sequences. This is done just for + // code clarity. + if ((*sit)->getAsCaseNode() == nullptr && (*sit)->getAsIfElseNode() == nullptr && + !IsSequence(*sit)) out << ";\n"; } @@ -1630,19 +1618,13 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) out << ")\n"; - if (sequence->size() > 1) - { - mInsideFunction = true; - TIntermNode *body = (*sequence)[1]; - // The function body node will output braces. - ASSERT(IsSequence(body)); - body->traverse(this); - mInsideFunction = false; - } - else - { - out << "{}\n"; - } + mInsideFunction = true; + ASSERT(sequence->size() == 2); + TIntermNode *body = (*sequence)[1]; + // The function body node will output braces. + ASSERT(IsSequence(body)); + body->traverse(this); + mInsideFunction = false; mCurrentFunctionMetadata = nullptr; @@ -1677,6 +1659,12 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) out << DisambiguateFunctionName(node->getSequence()); out << (lod0 ? "Lod0(" : "("); } + else if (node->getNameObj().isInternal()) + { + // This path is used for internal functions that don't have their definitions in the + // AST, such as precision emulation functions. + out << DecorateFunctionIfNeeded(node->getNameObj()) << "("; + } else { TString name = TFunction::unmangleName(node->getNameObj().getString()); @@ -1705,7 +1693,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) TVector<TIntermSymbol *> samplerSymbols; TString structName = samplerNamePrefixFromStruct(typedArg); argType.createSamplerSymbols("angle_" + structName, "", - argType.isArray() ? argType.getArraySize() : 0, + argType.isArray() ? argType.getArraySize() : 0u, &samplerSymbols, nullptr); for (const TIntermSymbol *sampler : samplerSymbols) { @@ -1919,7 +1907,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) return true; } -void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) +void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node) { out << "if ("; @@ -1956,8 +1944,8 @@ void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) outputLineDirective(out, node->getFalseBlock()->getLine().first_line); - // Either this is "else if" or the falseBlock child node will output braces. - ASSERT(IsSequence(node->getFalseBlock()) || node->getFalseBlock()->getAsSelectionNode() != nullptr); + // The falseBlock child node will output braces. + ASSERT(IsSequence(node->getFalseBlock())); node->getFalseBlock()->traverse(this); @@ -1974,11 +1962,18 @@ void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) } } -bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) +bool OutputHLSL::visitTernary(Visit, TIntermTernary *) +{ + // Ternary ops should have been already converted to something else in the AST. HLSL ternary + // operator doesn't short-circuit, so it's not the same as the GLSL ternary operator. + UNREACHABLE(); + return false; +} + +bool OutputHLSL::visitIfElse(Visit visit, TIntermIfElse *node) { TInfoSinkBase &out = getInfoSink(); - ASSERT(!node->usesTernaryOperator()); ASSERT(mInsideFunction); // D3D errors when there is a gradient operation in a loop in an unflattened if. @@ -1987,7 +1982,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) out << "FLATTEN "; } - writeSelection(out, node); + writeIfElse(out, node); return false; } @@ -2496,7 +2491,7 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol) { ASSERT(qualifier != EvqOut && qualifier != EvqInOut); TVector<TIntermSymbol *> samplerSymbols; - type.createSamplerSymbols("angle" + nameStr, "", 0, &samplerSymbols, nullptr); + type.createSamplerSymbols("angle" + nameStr, "", 0u, &samplerSymbols, nullptr); for (const TIntermSymbol *sampler : samplerSymbols) { if (mOutputType == SH_HLSL_4_1_OUTPUT) @@ -2864,14 +2859,14 @@ TString OutputHLSL::addArrayConstructIntoFunction(const TType& type) fnOut << "void " << function.functionName << "(out " << typeName << " a[" << type.getArraySize() << "]"; - for (int i = 0; i < type.getArraySize(); ++i) + for (unsigned int i = 0u; i < type.getArraySize(); ++i) { fnOut << ", " << typeName << " b" << i; } fnOut << ")\n" "{\n"; - for (int i = 0; i < type.getArraySize(); ++i) + for (unsigned int i = 0u; i < type.getArraySize(); ++i) { fnOut << " a[" << i << "] = b" << i << ";\n"; } diff --git a/chromium/third_party/angle/src/compiler/translator/OutputHLSL.h b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.h index e5204e419d9..ab4f9b3b9c8 100644 --- a/chromium/third_party/angle/src/compiler/translator/OutputHLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/OutputHLSL.h @@ -30,11 +30,14 @@ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols; class OutputHLSL : public TIntermTraverser { public: - OutputHLSL(sh::GLenum shaderType, int shaderVersion, - const TExtensionBehavior &extensionBehavior, - const char *sourcePath, ShShaderOutput outputType, - int numRenderTargets, const std::vector<Uniform> &uniforms, - int compileOptions); + OutputHLSL(sh::GLenum shaderType, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + const char *sourcePath, + ShShaderOutput outputType, + int numRenderTargets, + const std::vector<Uniform> &uniforms, + ShCompileOptions compileOptions); ~OutputHLSL(); @@ -56,9 +59,11 @@ class OutputHLSL : public TIntermTraverser void visitSymbol(TIntermSymbol*); void visitRaw(TIntermRaw*); void visitConstantUnion(TIntermConstantUnion*); + bool visitSwizzle(Visit visit, TIntermSwizzle *node) override; bool visitBinary(Visit visit, TIntermBinary*); bool visitUnary(Visit visit, TIntermUnary*); - bool visitSelection(Visit visit, TIntermSelection*); + bool visitTernary(Visit visit, TIntermTernary *); + bool visitIfElse(Visit visit, TIntermIfElse *); bool visitSwitch(Visit visit, TIntermSwitch *); bool visitCase(Visit visit, TIntermCase *); bool visitAggregate(Visit visit, TIntermAggregate*); @@ -101,7 +106,7 @@ class OutputHLSL : public TIntermTraverser TIntermTyped *expression); void writeDeferredGlobalInitializers(TInfoSinkBase &out); - void writeSelection(TInfoSinkBase &out, TIntermSelection *node); + void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node); // Returns the function name TString addStructEqualityFunction(const TStructure &structure); @@ -117,7 +122,7 @@ class OutputHLSL : public TIntermTraverser const TExtensionBehavior &mExtensionBehavior; const char *mSourcePath; const ShShaderOutput mOutputType; - int mCompileOptions; + ShCompileOptions mCompileOptions; bool mInsideFunction; diff --git a/chromium/third_party/angle/src/compiler/translator/ParseContext.cpp b/chromium/third_party/angle/src/compiler/translator/ParseContext.cpp index 9e836d1b5f8..99d696857b7 100644 --- a/chromium/third_party/angle/src/compiler/translator/ParseContext.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ParseContext.cpp @@ -132,12 +132,6 @@ bool TParseContext::parseVectorFields(const TString &compString, // //////////////////////////////////////////////////////////////////////// -// -// Track whether errors have occurred. -// -void TParseContext::recover() -{ -} // // Used by flex/bison to output all syntax and parsing errors. @@ -147,10 +141,7 @@ void TParseContext::error(const TSourceLoc &loc, const char *token, const char *extraInfo) { - pp::SourceLocation srcLoc; - srcLoc.file = loc.first_file; - srcLoc.line = loc.first_line; - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, srcLoc, reason, token, extraInfo); + mDiagnostics.error(loc, reason, token, extraInfo); } void TParseContext::warning(const TSourceLoc &loc, @@ -158,10 +149,7 @@ void TParseContext::warning(const TSourceLoc &loc, const char *token, const char *extraInfo) { - pp::SourceLocation srcLoc; - srcLoc.file = loc.first_file; - srcLoc.line = loc.first_line; - mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING, srcLoc, reason, token, extraInfo); + mDiagnostics.warning(loc, reason, token, extraInfo); } void TParseContext::outOfRangeError(bool isError, @@ -173,7 +161,6 @@ void TParseContext::outOfRangeError(bool isError, if (isError) { error(loc, reason, token, extraInfo); - recover(); } else { @@ -220,87 +207,73 @@ void TParseContext::binaryOpError(const TSourceLoc &line, error(line, " wrong operand types ", op, extraInfo.c_str()); } -bool TParseContext::precisionErrorCheck(const TSourceLoc &line, - TPrecision precision, - TBasicType type) +void TParseContext::checkPrecisionSpecified(const TSourceLoc &line, + TPrecision precision, + TBasicType type) { if (!mChecksPrecisionErrors) - return false; + return; + + if (precision != EbpUndefined && !SupportsPrecision(type)) + { + error(line, "illegal type for precision qualifier", getBasicString(type)); + } + if (precision == EbpUndefined) { switch (type) { case EbtFloat: error(line, "No precision specified for (float)", ""); - return true; + return; case EbtInt: case EbtUInt: UNREACHABLE(); // there's always a predeclared qualifier error(line, "No precision specified (int)", ""); - return true; + return; default: if (IsSampler(type)) { error(line, "No precision specified (sampler)", ""); - return true; + return; } } } - return false; } -// // Both test and if necessary, spit out an error, to see if the node is really // an l-value that can be operated on this way. -// -// Returns true if the was an error. -// -bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped *node) +bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node) { TIntermSymbol *symNode = node->getAsSymbolNode(); TIntermBinary *binaryNode = node->getAsBinaryNode(); + TIntermSwizzle *swizzleNode = node->getAsSwizzleNode(); - if (binaryNode) + if (swizzleNode) { - bool errorReturn; + bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand()); + if (ok && swizzleNode->hasDuplicateOffsets()) + { + error(line, " l-value of swizzle cannot have duplicate components", op); + return false; + } + return ok; + } + if (binaryNode) + { switch (binaryNode->getOp()) { case EOpIndexDirect: case EOpIndexIndirect: case EOpIndexDirectStruct: case EOpIndexDirectInterfaceBlock: - return lValueErrorCheck(line, op, binaryNode->getLeft()); - case EOpVectorSwizzle: - errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); - if (!errorReturn) - { - int offset[4] = {0, 0, 0, 0}; - - TIntermTyped *rightNode = binaryNode->getRight(); - TIntermAggregate *aggrNode = rightNode->getAsAggregate(); - - for (TIntermSequence::iterator p = aggrNode->getSequence()->begin(); - p != aggrNode->getSequence()->end(); p++) - { - int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0); - offset[value]++; - if (offset[value] > 1) - { - error(line, " l-value of swizzle cannot have duplicate components", op); - - return true; - } - } - } - - return errorReturn; + return checkCanBeLValue(line, op, binaryNode->getLeft()); default: break; } error(line, " l-value required", op); - - return true; + return false; } const char *symbol = 0; @@ -340,6 +313,27 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn case EvqPointCoord: message = "can't modify gl_PointCoord"; break; + case EvqNumWorkGroups: + message = "can't modify gl_NumWorkGroups"; + break; + case EvqWorkGroupSize: + message = "can't modify gl_WorkGroupSize"; + break; + case EvqWorkGroupID: + message = "can't modify gl_WorkGroupID"; + break; + case EvqLocalInvocationID: + message = "can't modify gl_LocalInvocationID"; + break; + case EvqGlobalInvocationID: + message = "can't modify gl_GlobalInvocationID"; + break; + case EvqLocalInvocationIndex: + message = "can't modify gl_LocalInvocationIndex"; + break; + case EvqComputeIn: + message = "can't modify work group size variable"; + break; default: // // Type that can't be written to? @@ -358,14 +352,14 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn { error(line, " l-value required", op); - return true; + return false; } // // Everything else is okay, no error. // if (message == 0) - return false; + return true; // // If we get here, we have an error and a message. @@ -385,67 +379,47 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn error(line, " l-value required", op, extraInfo.c_str()); } - return true; + return false; } -// // Both test, and if necessary spit out an error, to see if the node is really // a constant. -// -// Returns true if the was an error. -// -bool TParseContext::constErrorCheck(TIntermTyped *node) +void TParseContext::checkIsConst(TIntermTyped *node) { - if (node->getQualifier() == EvqConst) - return false; - - error(node->getLine(), "constant expression required", ""); - - return true; + if (node->getQualifier() != EvqConst) + { + error(node->getLine(), "constant expression required", ""); + } } -// // Both test, and if necessary spit out an error, to see if the node is really // an integer. -// -// Returns true if the was an error. -// -bool TParseContext::integerErrorCheck(TIntermTyped *node, const char *token) +void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token) { - if (node->isScalarInt()) - return false; - - error(node->getLine(), "integer expression required", token); - - return true; + if (!node->isScalarInt()) + { + error(node->getLine(), "integer expression required", token); + } } -// // Both test, and if necessary spit out an error, to see if we are currently // globally scoped. -// -// Returns true if the was an error. -// -bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char *token) +bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token) { - if (global) + if (!symbolTable.atGlobalLevel()) + { + error(line, "only allowed at global scope", token); return false; - - error(line, "only allowed at global scope", token); - + } return true; } -// // For now, keep it simple: if it starts "gl_", it's reserved, independent // of scope. Except, if the symbol table is at the built-in push-level, // which is when we are parsing built-ins. // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a // webgl shader. -// -// Returns true if there was an error. -// -bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString &identifier) +bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const TString &identifier) { static const char *reservedErrMsg = "reserved built-in name"; if (!symbolTable.atBuiltInLevel()) @@ -453,24 +427,19 @@ bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString &id if (identifier.compare(0, 3, "gl_") == 0) { error(line, reservedErrMsg, "gl_"); - return true; + return false; } if (IsWebGLBasedSpec(mShaderSpec)) { if (identifier.compare(0, 6, "webgl_") == 0) { error(line, reservedErrMsg, "webgl_"); - return true; + return false; } if (identifier.compare(0, 7, "_webgl_") == 0) { error(line, reservedErrMsg, "_webgl_"); - return true; - } - if (mShaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) - { - error(line, reservedErrMsg, "css_"); - return true; + return false; } } if (identifier.find("__") != TString::npos) @@ -479,28 +448,22 @@ bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString &id "identifiers containing two consecutive underscores (__) are reserved as " "possible future keywords", identifier.c_str()); - return true; + return false; } } - return false; + return true; } -// // Make sure there is enough data provided to the constructor to build // something of the type of the constructor. Also returns the type of // the constructor. -// -// Returns true if there was an error in construction. -// -bool TParseContext::constructorErrorCheck(const TSourceLoc &line, - TIntermNode *argumentsNode, - TFunction &function, - TOperator op, - TType *type) +bool TParseContext::checkConstructorArguments(const TSourceLoc &line, + TIntermNode *argumentsNode, + const TFunction &function, + TOperator op, + const TType &type) { - *type = function.getReturnType(); - bool constructingMatrix = false; switch (op) { @@ -526,7 +489,6 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc &line, // size_t size = 0; - bool constType = true; bool full = false; bool overFull = false; bool matrixInMatrix = false; @@ -540,75 +502,68 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc &line, matrixInMatrix = true; if (full) overFull = true; - if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize()) + if (op != EOpConstructStruct && !type.isArray() && size >= type.getObjectSize()) full = true; - if (param.type->getQualifier() != EvqConst) - constType = false; if (param.type->isArray()) arrayArg = true; } - if (constType) - type->setQualifier(EvqConst); - - if (type->isArray()) + if (type.isArray()) { - if (type->isUnsizedArray()) - { - type->setArraySize(static_cast<int>(function.getParamCount())); - } - else if (static_cast<size_t>(type->getArraySize()) != function.getParamCount()) + // The size of an unsized constructor should already have been determined. + ASSERT(!type.isUnsizedArray()); + if (static_cast<size_t>(type.getArraySize()) != function.getParamCount()) { error(line, "array constructor needs one argument per array element", "constructor"); - return true; + return false; } } if (arrayArg && op != EOpConstructStruct) { error(line, "constructing from a non-dereferenced array", "constructor"); - return true; + return false; } - if (matrixInMatrix && !type->isArray()) + if (matrixInMatrix && !type.isArray()) { if (function.getParamCount() != 1) { error(line, "constructing matrix from matrix can only take one argument", "constructor"); - return true; + return false; } } if (overFull) { error(line, "too many arguments", "constructor"); - return true; + return false; } - if (op == EOpConstructStruct && !type->isArray() && - type->getStruct()->fields().size() != function.getParamCount()) + if (op == EOpConstructStruct && !type.isArray() && + type.getStruct()->fields().size() != function.getParamCount()) { error(line, "Number of constructor parameters does not match the number of structure fields", "constructor"); - return true; + return false; } - if (!type->isMatrix() || !matrixInMatrix) + if (!type.isMatrix() || !matrixInMatrix) { - if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || - (op == EOpConstructStruct && size < type->getObjectSize())) + if ((op != EOpConstructStruct && size != 1 && size < type.getObjectSize()) || + (op == EOpConstructStruct && size < type.getObjectSize())) { error(line, "not enough data provided for construction", "constructor"); - return true; + return false; } } if (argumentsNode == nullptr) { error(line, "constructor does not have any arguments", "constructor"); - return true; + return false; } TIntermAggregate *argumentsAgg = argumentsNode->getAsAggregate(); @@ -619,16 +574,48 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc &line, if (op != EOpConstructStruct && IsSampler(argTyped->getBasicType())) { error(line, "cannot convert a sampler", "constructor"); - return true; + return false; } if (argTyped->getBasicType() == EbtVoid) { error(line, "cannot convert a void", "constructor"); - return true; + return false; } } - return false; + if (type.isArray()) + { + // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of + // the array. + for (TIntermNode *&argNode : *argumentsAgg->getSequence()) + { + const TType &argType = argNode->getAsTyped()->getType(); + // It has already been checked that the argument is not an array. + ASSERT(!argType.isArray()); + if (!argType.sameElementType(type)) + { + error(line, "Array constructor argument has an incorrect type", "Error"); + return false; + } + } + } + else if (op == EOpConstructStruct) + { + const TFieldList &fields = type.getStruct()->fields(); + TIntermSequence *args = argumentsAgg->getSequence(); + + for (size_t i = 0; i < fields.size(); i++) + { + if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type()) + { + error(line, "Structure constructor arguments do not match structure fields", + "Error"); + return false; + } + } + } + + return true; } // This function checks to see if a void variable has been declared and raise an error message for @@ -636,53 +623,41 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc &line, // // returns true in case of an error // -bool TParseContext::voidErrorCheck(const TSourceLoc &line, +bool TParseContext::checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type) { if (type == EbtVoid) { error(line, "illegal use of type 'void'", identifier.c_str()); - return true; + return false; } - return false; + return true; } // This function checks to see if the node (for the expression) contains a scalar boolean expression -// or not -// -// returns true in case of an error -// -bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped *type) +// or not. +void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type) { if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) { error(line, "boolean expression expected", ""); - return true; } - - return false; } // This function checks to see if the node (for the expression) contains a scalar boolean expression -// or not -// -// returns true in case of an error -// -bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType &pType) +// or not. +void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType) { - if (pType.type != EbtBool || pType.isAggregate()) + if (pType.getBasicType() != EbtBool || pType.isAggregate()) { error(line, "boolean expression expected", ""); - return true; } - - return false; } -bool TParseContext::samplerErrorCheck(const TSourceLoc &line, - const TPublicType &pType, +bool TParseContext::checkIsNotSampler(const TSourceLoc &line, + const TTypeSpecifierNonArray &pType, const char *reason) { if (pType.type == EbtStruct) @@ -690,46 +665,49 @@ bool TParseContext::samplerErrorCheck(const TSourceLoc &line, if (containsSampler(*pType.userDef)) { error(line, reason, getBasicString(pType.type), "(structure contains a sampler)"); - - return true; + return false; } - return false; + return true; } else if (IsSampler(pType.type)) { error(line, reason, getBasicString(pType.type)); - - return true; + return false; } - return false; + return true; } -bool TParseContext::locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType) +void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, + const TPublicType &pType) { if (pType.layoutQualifier.location != -1) { error(line, "location must only be specified for a single input or output variable", "location"); - return true; } +} - return false; +void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier) +{ + if (layoutQualifier.location != -1) + { + error(location, "invalid layout qualifier:", "location", + "only valid on program inputs and outputs"); + } } -bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, - TQualifier qualifier, - const TType &type) +void TParseContext::checkOutParameterIsNotSampler(const TSourceLoc &line, + TQualifier qualifier, + const TType &type) { if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) { error(line, "samplers cannot be output parameters", type.getBasicString()); - return true; } - - return false; } bool TParseContext::containsSampler(const TType &type) @@ -750,12 +728,8 @@ bool TParseContext::containsSampler(const TType &type) return false; } -// // Do size checking for an array type's size. -// -// Returns true if there was an error. -// -bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size) +unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr) { TIntermConstantUnion *constant = expr->getAsConstantUnion(); @@ -765,36 +739,32 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *ex if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt()) { error(line, "array size must be a constant integer expression", ""); - size = 1; - return true; + return 1u; } - unsigned int unsignedSize = 0; + unsigned int size = 0u; if (constant->getBasicType() == EbtUInt) { - unsignedSize = constant->getUConst(0); - size = static_cast<int>(unsignedSize); + size = constant->getUConst(0); } else { - size = constant->getIConst(0); + int signedSize = constant->getIConst(0); - if (size < 0) + if (signedSize < 0) { error(line, "array size must be non-negative", ""); - size = 1; - return true; + return 1u; } - unsignedSize = static_cast<unsigned int>(size); + size = static_cast<unsigned int>(signedSize); } - if (size == 0) + if (size == 0u) { error(line, "array size must be greater than zero", ""); - size = 1; - return true; + return 1u; } // The size of arrays is restricted here to prevent issues further down the @@ -802,70 +772,72 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *ex // 4096 registers so this should be reasonable even for aggressively optimizable code. const unsigned int sizeLimit = 65536; - if (unsignedSize > sizeLimit) + if (size > sizeLimit) { error(line, "array size too large", ""); - size = 1; - return true; + return 1u; } - return false; + return size; } -// // See if this qualifier can be an array. -// -// Returns true if there is an error. -// -bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type) +bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line, + const TPublicType &elementQualifier) { - if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || - (type.qualifier == EvqConst && mShaderVersion < 300)) + if ((elementQualifier.qualifier == EvqAttribute) || + (elementQualifier.qualifier == EvqVertexIn) || + (elementQualifier.qualifier == EvqConst && mShaderVersion < 300)) { error(line, "cannot declare arrays of this qualifier", - TType(type).getCompleteString().c_str()); - return true; + TType(elementQualifier).getQualifierString()); + return false; } - return false; + return true; } -// -// See if this type can be an array. -// -// Returns true if there is an error. -// -bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type) +// See if this element type can be formed into an array. +bool TParseContext::checkIsValidTypeForArray(const TSourceLoc &line, const TPublicType &elementType) { // // Can the type be an array? // - if (type.array) + if (elementType.array) { - error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str()); - return true; + error(line, "cannot declare arrays of arrays", + TType(elementType).getCompleteString().c_str()); + return false; } // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere. // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section // 4.3.4). - if (mShaderVersion >= 300 && type.type == EbtStruct && sh::IsVarying(type.qualifier)) + if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct && + sh::IsVarying(elementType.qualifier)) { error(line, "cannot declare arrays of structs of this qualifier", - TType(type).getCompleteString().c_str()); - return true; + TType(elementType).getCompleteString().c_str()); + return false; } + return true; +} + +// Check if this qualified element type can be formed into an array. +bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation, + const TPublicType &elementType) +{ + if (checkIsValidTypeForArray(indexLocation, elementType)) + { + return checkIsValidQualifierForArray(indexLocation, elementType); + } return false; } -// // Enforce non-initializer type/qualifier rules. -// -// Returns true if there was an error. -// -bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, - const TString &identifier, - TPublicType *type) +void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, + const TString &identifier, + TPublicType *type) { ASSERT(type != nullptr); if (type->qualifier == EvqConst) @@ -886,15 +858,12 @@ bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, { error(line, "variables with qualifier 'const' must be initialized", identifier.c_str()); } - - return true; + return; } if (type->isUnsizedArray()) { error(line, "implicitly sized arrays need to be initialized", identifier.c_str()); - return true; } - return false; } // Do some simple checks that are shared between all variable declarations, @@ -909,18 +878,18 @@ bool TParseContext::declareVariable(const TSourceLoc &line, { ASSERT((*variable) == nullptr); - bool needsReservedErrorCheck = true; + bool needsReservedCheck = true; // gl_LastFragData may be redeclared with a new precision qualifier if (type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0) { const TVariable *maxDrawBuffers = static_cast<const TVariable *>( symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion)); - if (type.getArraySize() == maxDrawBuffers->getConstPointer()->getIConst()) + if (static_cast<int>(type.getArraySize()) == maxDrawBuffers->getConstPointer()->getIConst()) { if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion)) { - needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension()); + needsReservedCheck = !checkCanUseExtension(line, builtInSymbol->getExtension()); } } else @@ -931,7 +900,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line, } } - if (needsReservedErrorCheck && reservedErrorCheck(line, identifier)) + if (needsReservedCheck && !checkIsNotReserved(line, identifier)) return false; (*variable) = new TVariable(&identifier, type); @@ -942,65 +911,59 @@ bool TParseContext::declareVariable(const TSourceLoc &line, return false; } - if (voidErrorCheck(line, identifier, type.getBasicType())) + if (!checkIsNonVoid(line, identifier, type.getBasicType())) return false; return true; } -bool TParseContext::paramErrorCheck(const TSourceLoc &line, - TQualifier qualifier, - TQualifier paramQualifier, - TType *type) +void TParseContext::checkIsParameterQualifierValid( + const TSourceLoc &line, + const TTypeQualifierBuilder &typeQualifierBuilder, + TType *type) { - if (qualifier != EvqConst && qualifier != EvqTemporary) - { - error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier)); - return true; - } - if (qualifier == EvqConst && paramQualifier != EvqIn) + TTypeQualifier typeQualifier = typeQualifierBuilder.getParameterTypeQualifier(&mDiagnostics); + + if (typeQualifier.qualifier == EvqOut || typeQualifier.qualifier == EvqInOut) { - error(line, "qualifier not allowed with ", getQualifierString(qualifier), - getQualifierString(paramQualifier)); - return true; + checkOutParameterIsNotSampler(line, typeQualifier.qualifier, *type); } - if (qualifier == EvqConst) - type->setQualifier(EvqConstReadOnly); - else - type->setQualifier(paramQualifier); + type->setQualifier(typeQualifier.qualifier); - return false; + if (typeQualifier.precision != EbpUndefined) + { + type->setPrecision(typeQualifier.precision); + } } -bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString &extension) +bool TParseContext::checkCanUseExtension(const TSourceLoc &line, const TString &extension) { const TExtensionBehavior &extBehavior = extensionBehavior(); TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str()); if (iter == extBehavior.end()) { error(line, "extension", extension.c_str(), "is not supported"); - return true; + return false; } // In GLSL ES, an extension's default behavior is "disable". if (iter->second == EBhDisable || iter->second == EBhUndefined) { error(line, "extension", extension.c_str(), "is disabled"); - return true; + return false; } if (iter->second == EBhWarn) { warning(line, "extension", extension.c_str(), "is being used"); - return false; + return true; } - return false; + return true; } // These checks are common for all declarations starting a declarator list, and declarators that // follow an empty declaration. -// -bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, +void TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation) { switch (publicType.qualifier) @@ -1010,11 +973,12 @@ bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, case EvqAttribute: case EvqVertexIn: case EvqFragmentOut: - if (publicType.type == EbtStruct) + case EvqComputeIn: + if (publicType.getBasicType() == EbtStruct) { error(identifierLocation, "cannot be used with a structure", getQualifierString(publicType.qualifier)); - return true; + return; } default: @@ -1022,9 +986,10 @@ bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, } if (publicType.qualifier != EvqUniform && - samplerErrorCheck(identifierLocation, publicType, "samplers must be uniform")) + !checkIsNotSampler(identifierLocation, publicType.typeSpecifierNonArray, + "samplers must be uniform")) { - return true; + return; } // check for layout qualifier issues @@ -1035,7 +1000,7 @@ bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking), "only valid for interface blocks"); - return true; + return; } if (layoutQualifier.blockStorage != EbsUnspecified) @@ -1043,59 +1008,83 @@ bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage), "only valid for interface blocks"); - return true; + return; } - if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut && - layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier)) + if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut) { - return true; + checkLocationIsNotSpecified(identifierLocation, publicType.layoutQualifier); } +} - return false; +void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location, + const TString &layoutQualifierName, + int versionRequired) +{ + + if (mShaderVersion < versionRequired) + { + error(location, "invalid layout qualifier:", layoutQualifierName.c_str(), "not supported"); + } } -bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, - const TLayoutQualifier &layoutQualifier) +bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier) { - if (layoutQualifier.location != -1) + const sh::WorkGroupSize &localSize = layoutQualifier.localSize; + for (size_t i = 0u; i < localSize.size(); ++i) { - error(location, "invalid layout qualifier:", "location", - "only valid on program inputs and outputs"); - return true; + if (localSize[i] != -1) + { + error(location, "invalid layout qualifier:", getWorkGroupSizeString(i), + "only valid when used with 'in' in a compute shader global layout declaration"); + return false; + } } - return false; + return true; } -bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, - TIntermAggregate *aggregate) +void TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, + TIntermAggregate *fnCall) { for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) { TQualifier qual = fnCandidate->getParam(i).type->getQualifier(); if (qual == EvqOut || qual == EvqInOut) { - TIntermTyped *node = (*(aggregate->getSequence()))[i]->getAsTyped(); - if (lValueErrorCheck(node->getLine(), "assign", node)) + TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped(); + if (!checkCanBeLValue(argument->getLine(), "assign", argument)) { - error(node->getLine(), + error(argument->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); - recover(); - return true; + return; } } } - return false; } -void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier, - const TSourceLoc &invariantLocation) +void TParseContext::checkInvariantVariableQualifier(bool invariant, + const TQualifier qualifier, + const TSourceLoc &invariantLocation) { - if (!sh::IsVaryingOut(qualifier) && qualifier != EvqFragmentOut) + if (!invariant) + return; + + if (mShaderVersion < 300) + { + // input variables in the fragment shader can be also qualified as invariant + if (!sh::CanBeInvariantESSL1(qualifier)) + { + error(invariantLocation, "Cannot be qualified as invariant.", "invariant"); + } + } + else { - error(invariantLocation, "Only out variables can be invariant.", "invariant"); - recover(); + if (!sh::CanBeInvariantESSL3OrGreater(qualifier)) + { + error(invariantLocation, "Cannot be qualified as invariant.", "invariant"); + } } } @@ -1132,6 +1121,23 @@ void TParseContext::handlePragmaDirective(const TSourceLoc &loc, mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl); } +sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const +{ + sh::WorkGroupSize result; + for (size_t i = 0u; i < result.size(); ++i) + { + if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1) + { + result[i] = 1; + } + else + { + result[i] = mComputeShaderLocalSize[i]; + } + } + return result; +} + ///////////////////////////////////////////////////////////////////////////////// // // Non-Errors. @@ -1147,22 +1153,19 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, if (!symbol) { error(location, "undeclared identifier", name->c_str()); - recover(); } else if (!symbol->isVariable()) { error(location, "variable expected", name->c_str()); - recover(); } else { variable = static_cast<const TVariable *>(symbol); if (symbolTable.findBuiltIn(variable->getName(), mShaderVersion) && - !variable->getExtension().empty() && - extensionErrorCheck(location, variable->getExtension())) + !variable->getExtension().empty()) { - recover(); + checkCanUseExtension(location, variable->getExtension()); } // Reject shaders using both gl_FragData and gl_FragColor @@ -1194,7 +1197,15 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, " and (gl_FragColor, gl_SecondaryFragColorEXT)"; } error(location, errorMessage, name->c_str()); - recover(); + } + + // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables + if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared && + qualifier == EvqWorkGroupSize) + { + error(location, + "It is an error to use gl_WorkGroupSize before declaring the local group size", + "gl_WorkGroupSize"); } } @@ -1376,66 +1387,82 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, return false; } -TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, - bool invariant, - TLayoutQualifier layoutQualifier, +TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, const TPublicType &typeSpecifier) { + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics); + TPublicType returnType = typeSpecifier; - returnType.qualifier = qualifier; - returnType.invariant = invariant; - returnType.layoutQualifier = layoutQualifier; + returnType.qualifier = typeQualifier.qualifier; + returnType.invariant = typeQualifier.invariant; + returnType.layoutQualifier = typeQualifier.layoutQualifier; + returnType.precision = typeSpecifier.precision; + + if (typeQualifier.precision != EbpUndefined) + { + returnType.precision = typeQualifier.precision; + } + + checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision, + typeSpecifier.getBasicType()); + + checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier, + typeSpecifier.getLine()); + + checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier); if (mShaderVersion < 300) { if (typeSpecifier.array) { - error(typeSpecifier.line, "not supported", "first-class array"); - recover(); + error(typeSpecifier.getLine(), "not supported", "first-class array"); returnType.clearArrayness(); } - if (qualifier == EvqAttribute && - (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + if (returnType.qualifier == EvqAttribute && + (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt)) { - error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); - recover(); + error(typeSpecifier.getLine(), "cannot be bool or int", + getQualifierString(returnType.qualifier)); } - if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) && - (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) && + (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt)) { - error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); - recover(); + error(typeSpecifier.getLine(), "cannot be bool or int", + getQualifierString(returnType.qualifier)); } } else { - if (!layoutQualifier.isEmpty()) + if (!returnType.layoutQualifier.isEmpty()) { - if (globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout")) - { - recover(); - } + checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout"); } - if (sh::IsVarying(qualifier) || qualifier == EvqVertexIn || qualifier == EvqFragmentOut) + if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn || + returnType.qualifier == EvqFragmentOut) { - es3InputOutputTypeCheck(qualifier, typeSpecifier, typeSpecifier.line); + checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier, + typeSpecifier.getLine()); + } + if (returnType.qualifier == EvqComputeIn) + { + error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size", + "in"); } } return returnType; } -void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, - const TPublicType &type, - const TSourceLoc &qualifierLocation) +void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier, + const TPublicType &type, + const TSourceLoc &qualifierLocation) { // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere. - if (type.type == EbtBool) + if (type.getBasicType() == EbtBool) { error(qualifierLocation, "cannot be bool", getQualifierString(qualifier)); - recover(); } // Specific restrictions apply for vertex shader inputs and fragment shader outputs. @@ -1446,16 +1473,14 @@ void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, if (type.array) { error(qualifierLocation, "cannot be array", getQualifierString(qualifier)); - recover(); } // Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck return; case EvqFragmentOut: // ESSL 3.00 section 4.3.6 - if (type.isMatrix()) + if (type.typeSpecifierNonArray.isMatrix()) { error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier)); - recover(); } // Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck return; @@ -1466,16 +1491,15 @@ void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of // restrictions. bool typeContainsIntegers = - (type.type == EbtInt || type.type == EbtUInt || type.isStructureContainingType(EbtInt) || - type.isStructureContainingType(EbtUInt)); + (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt || + type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt)); if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut) { error(qualifierLocation, "must use 'flat' interpolation here", getQualifierString(qualifier)); - recover(); } - if (type.type == EbtStruct) + if (type.getBasicType() == EbtStruct) { // ESSL 3.00 sections 4.3.4 and 4.3.6. // These restrictions are only implied by the ESSL 3.00 spec, but @@ -1484,25 +1508,21 @@ void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, { error(qualifierLocation, "cannot be an array of structures", getQualifierString(qualifier)); - recover(); } if (type.isStructureContainingArrays()) { error(qualifierLocation, "cannot be a structure containing an array", getQualifierString(qualifier)); - recover(); } if (type.isStructureContainingType(EbtStruct)) { error(qualifierLocation, "cannot be a structure containing a structure", getQualifierString(qualifier)); - recover(); } if (type.isStructureContainingType(EbtBool)) { error(qualifierLocation, "cannot be a structure containing a bool", getQualifierString(qualifier)); - recover(); } } } @@ -1511,8 +1531,35 @@ TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType, const TSourceLoc &identifierOrTypeLocation, const TString &identifier) { - TIntermSymbol *symbol = - intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation); + TType type(publicType); + if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) && + mDirectiveHandler.pragma().stdgl.invariantAll) + { + TQualifier qualifier = type.getQualifier(); + + // The directive handler has already taken care of rejecting invalid uses of this pragma + // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all + // affected variable declarations: + // + // 1. Built-in special variables which are inputs to the fragment shader. (These are handled + // elsewhere, in TranslatorGLSL.) + // + // 2. Outputs from vertex shaders in ESSL 1.00 and 3.00 (EvqVaryingOut and EvqVertexOut). It + // is actually less likely that there will be bugs in the handling of ESSL 3.00 shaders, but + // the way this is currently implemented we have to enable this compiler option before + // parsing the shader and determining the shading language version it uses. If this were + // implemented as a post-pass, the workaround could be more targeted. + // + // 3. Inputs in ESSL 1.00 fragment shaders (EvqVaryingIn). This is somewhat in violation of + // the specification, but there are desktop OpenGL drivers that expect that this is the + // behavior of the #pragma when specified in ESSL 1.00 fragment shaders. + if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut || qualifier == EvqVaryingIn) + { + type.setInvariant(true); + } + } + + TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, type, identifierOrTypeLocation); bool emptyDeclaration = (identifier == ""); @@ -1530,21 +1577,18 @@ TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType, } else { - if (singleDeclarationErrorCheck(publicType, identifierOrTypeLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierOrTypeLocation); - if (nonInitErrorCheck(identifierOrTypeLocation, identifier, &publicType)) - recover(); + checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &publicType); TVariable *variable = nullptr; - if (!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable)) - recover(); + declareVariable(identifierOrTypeLocation, identifier, type, &variable); if (variable && symbol) symbol->setId(variable->getUniqueId()); } - return intermediate.makeAggregate(symbol, identifierOrTypeLocation); + return TIntermediate::MakeAggregate(symbol, identifierOrTypeLocation); } TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType, @@ -1555,38 +1599,27 @@ TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &public { mDeferredSingleDeclarationErrorCheck = false; - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierLocation); - if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) - recover(); + checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType); - if (arrayTypeErrorCheck(indexLocation, publicType) || - arrayQualifierErrorCheck(indexLocation, publicType)) - { - recover(); - } + checkIsValidTypeAndQualifierForArray(indexLocation, publicType); TType arrayType(publicType); - int size; - if (arraySizeErrorCheck(identifierLocation, indexExpression, size)) - { - recover(); - } + unsigned int size = checkIsValidArraySize(identifierLocation, indexExpression); // Make the type an array even if size check failed. // This ensures useless error messages regarding the variable's non-arrayness won't follow. arrayType.setArraySize(size); TVariable *variable = nullptr; - if (!declareVariable(identifierLocation, identifier, arrayType, &variable)) - recover(); + declareVariable(identifierLocation, identifier, arrayType, &variable); TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation); if (variable && symbol) symbol->setId(variable->getUniqueId()); - return intermediate.makeAggregate(symbol, identifierLocation); + return TIntermediate::MakeAggregate(symbol, identifierLocation); } TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType, @@ -1597,8 +1630,7 @@ TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &p { mDeferredSingleDeclarationErrorCheck = false; - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierLocation); TIntermNode *intermNode = nullptr; if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode)) @@ -1606,11 +1638,10 @@ TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &p // // Build intermediate representation // - return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr; + return intermNode ? TIntermediate::MakeAggregate(intermNode, initLocation) : nullptr; } else { - recover(); return nullptr; } } @@ -1626,24 +1657,18 @@ TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration( { mDeferredSingleDeclarationErrorCheck = false; - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierLocation); - if (arrayTypeErrorCheck(indexLocation, publicType) || - arrayQualifierErrorCheck(indexLocation, publicType)) - { - recover(); - } + checkIsValidTypeAndQualifierForArray(indexLocation, publicType); TPublicType arrayType(publicType); - int size = 0; + unsigned int size = 0u; // If indexExpression is nullptr, then the array will eventually get its size implicitly from // the initializer. - if (indexExpression != nullptr && - arraySizeErrorCheck(identifierLocation, indexExpression, size)) + if (indexExpression != nullptr) { - recover(); + size = checkIsValidArraySize(identifierLocation, indexExpression); } // Make the type an array even if size check failed. // This ensures useless error messages regarding the variable's non-arrayness won't follow. @@ -1653,53 +1678,66 @@ TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration( TIntermNode *initNode = nullptr; if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode)) { - return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr; + return initNode ? TIntermediate::MakeAggregate(initNode, initLocation) : nullptr; } else { - recover(); return nullptr; } } -TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc, - const TSourceLoc &identifierLoc, - const TString *identifier, - const TSymbol *symbol) +TIntermAggregate *TParseContext::parseInvariantDeclaration( + const TTypeQualifierBuilder &typeQualifierBuilder, + const TSourceLoc &identifierLoc, + const TString *identifier, + const TSymbol *symbol) { - // invariant declaration - if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying")) + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics); + + if (!typeQualifier.invariant) { - recover(); + error(identifierLoc, "Expected invariant", identifier->c_str()); + return nullptr; + } + if (!checkIsAtGlobalLevel(identifierLoc, "invariant varying")) + { + return nullptr; } - if (!symbol) { error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str()); - recover(); return nullptr; } - else + if (!IsQualifierUnspecified(typeQualifier.qualifier)) { - const TString kGlFrontFacing("gl_FrontFacing"); - if (*identifier == kGlFrontFacing) - { - error(identifierLoc, "identifier should not be declared as invariant", - identifier->c_str()); - recover(); - return nullptr; - } - symbolTable.addInvariantVarying(std::string(identifier->c_str())); - const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol); - ASSERT(variable); - const TType &type = variable->getType(); - TIntermSymbol *intermSymbol = - intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc); - - TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc); - aggregate->setOp(EOpInvariantDeclaration); - return aggregate; + error(identifierLoc, "invariant declaration specifies qualifier", + getQualifierString(typeQualifier.qualifier)); + } + if (typeQualifier.precision != EbpUndefined) + { + error(identifierLoc, "invariant declaration specifies precision", + getPrecisionString(typeQualifier.precision)); + } + if (!typeQualifier.layoutQualifier.isEmpty()) + { + error(identifierLoc, "invariant declaration specifies layout", "'layout'"); } + + const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol); + ASSERT(variable); + const TType &type = variable->getType(); + + checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(), + typeQualifier.line); + + symbolTable.addInvariantVarying(std::string(identifier->c_str())); + + TIntermSymbol *intermSymbol = + intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc); + + TIntermAggregate *aggregate = TIntermediate::MakeAggregate(intermSymbol, identifierLoc); + aggregate->setOp(EOpInvariantDeclaration); + return aggregate; } TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, @@ -1711,20 +1749,16 @@ TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, // not performed. if (mDeferredSingleDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierLocation); mDeferredSingleDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); - if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) - recover(); + checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType); TVariable *variable = nullptr; - if (!declareVariable(identifierLocation, identifier, TType(publicType), &variable)) - recover(); + declareVariable(identifierLocation, identifier, TType(publicType), &variable); TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation); @@ -1745,35 +1779,22 @@ TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, // not performed. if (mDeferredSingleDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierLocation); mDeferredSingleDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); - if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) - recover(); + checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &publicType); - if (arrayTypeErrorCheck(arrayLocation, publicType) || - arrayQualifierErrorCheck(arrayLocation, publicType)) - { - recover(); - } - else + if (checkIsValidTypeAndQualifierForArray(arrayLocation, publicType)) { TType arrayType = TType(publicType); - int size; - if (arraySizeErrorCheck(arrayLocation, indexExpression, size)) - { - recover(); - } + unsigned int size = checkIsValidArraySize(arrayLocation, indexExpression); arrayType.setArraySize(size); TVariable *variable = nullptr; - if (!declareVariable(identifierLocation, identifier, arrayType, &variable)) - recover(); + declareVariable(identifierLocation, identifier, arrayType, &variable); TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation); @@ -1797,13 +1818,11 @@ TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicTy // not performed. if (mDeferredSingleDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierLocation); mDeferredSingleDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); TIntermNode *intermNode = nullptr; if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode)) @@ -1822,7 +1841,6 @@ TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicTy } else { - recover(); return nullptr; } } @@ -1840,29 +1858,22 @@ TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &pub // not performed. if (mDeferredSingleDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + singleDeclarationErrorCheck(publicType, identifierLocation); mDeferredSingleDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); - if (arrayTypeErrorCheck(indexLocation, publicType) || - arrayQualifierErrorCheck(indexLocation, publicType)) - { - recover(); - } + checkIsValidTypeAndQualifierForArray(indexLocation, publicType); TPublicType arrayType(publicType); - int size = 0; + unsigned int size = 0u; // If indexExpression is nullptr, then the array will eventually get its size implicitly from // the initializer. - if (indexExpression != nullptr && - arraySizeErrorCheck(identifierLocation, indexExpression, size)) + if (indexExpression != nullptr) { - recover(); + size = checkIsValidArraySize(identifierLocation, indexExpression); } // Make the type an array even if size check failed. // This ensures useless error messages regarding the variable's non-arrayness won't follow. @@ -1883,45 +1894,115 @@ TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &pub } else { - recover(); return nullptr; } } -void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) +void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder) { - if (typeQualifier.qualifier != EvqUniform) - { - error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), - "global layout must be uniform"); - recover(); - return; - } - + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics); const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier; - ASSERT(!layoutQualifier.isEmpty()); - if (mShaderVersion < 300) + checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier, + typeQualifier.line); + + // It should never be the case, but some strange parser errors can send us here. + if (layoutQualifier.isEmpty()) { - error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout"); - recover(); + error(typeQualifier.line, "Error during layout qualifier parsing.", "?"); return; } - if (layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier)) + if (!layoutQualifier.isCombinationValid()) { - recover(); + error(typeQualifier.line, "invalid combination:", "layout"); return; } - if (layoutQualifier.matrixPacking != EmpUnspecified) + if (typeQualifier.qualifier == EvqComputeIn) { - mDefaultMatrixPacking = layoutQualifier.matrixPacking; - } + if (mComputeShaderLocalSizeDeclared && + !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize)) + { + error(typeQualifier.line, "Work group size does not match the previous declaration", + "layout"); + return; + } - if (layoutQualifier.blockStorage != EbsUnspecified) + if (mShaderVersion < 310) + { + error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout"); + return; + } + + if (!layoutQualifier.localSize.isAnyValueSet()) + { + error(typeQualifier.line, "No local work group size specified", "layout"); + return; + } + + const TVariable *maxComputeWorkGroupSize = static_cast<const TVariable *>( + symbolTable.findBuiltIn("gl_MaxComputeWorkGroupSize", mShaderVersion)); + + const TConstantUnion *maxComputeWorkGroupSizeData = + maxComputeWorkGroupSize->getConstPointer(); + + for (size_t i = 0u; i < layoutQualifier.localSize.size(); ++i) + { + if (layoutQualifier.localSize[i] != -1) + { + mComputeShaderLocalSize[i] = layoutQualifier.localSize[i]; + const int maxComputeWorkGroupSizeValue = maxComputeWorkGroupSizeData[i].getIConst(); + if (mComputeShaderLocalSize[i] < 1 || + mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue) + { + std::stringstream errorMessageStream; + errorMessageStream << "Value must be at least 1 and no greater than " + << maxComputeWorkGroupSizeValue; + const std::string &errorMessage = errorMessageStream.str(); + + error(typeQualifier.line, "invalid value:", getWorkGroupSizeString(i), + errorMessage.c_str()); + return; + } + } + } + + mComputeShaderLocalSizeDeclared = true; + } + else { - mDefaultBlockStorage = layoutQualifier.blockStorage; + + if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier)) + { + return; + } + + if (typeQualifier.qualifier != EvqUniform) + { + error(typeQualifier.line, "invalid qualifier:", + getQualifierString(typeQualifier.qualifier), "global layout must be uniform"); + return; + } + + if (mShaderVersion < 300) + { + error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and above", + "layout"); + return; + } + + checkLocationIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier); + + if (layoutQualifier.matrixPacking != EmpUnspecified) + { + mDefaultMatrixPacking = layoutQualifier.matrixPacking; + } + + if (layoutQualifier.blockStorage != EbsUnspecified) + { + mDefaultBlockStorage = layoutQualifier.blockStorage; + } } } @@ -1938,7 +2019,6 @@ TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction // ESSL 1.00.17 section 4.2.7. // Doesn't apply to ESSL 3.00.4: see section 4.2.3. error(location, "duplicate function prototype declarations are not allowed", "function"); - recover(); } symbolTableFunction->setHasPrototypeDeclaration(); @@ -1973,7 +2053,6 @@ TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction { // ESSL 3.00.4 section 4.2.4. error(location, "local function prototype declarations are not allowed", "function"); - recover(); } return prototype; @@ -1984,23 +2063,31 @@ TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function TIntermAggregate *functionBody, const TSourceLoc &location) { - //?? Check that all paths return a value if return type != void ? - // May be best done as post process phase on intermediate code + // Check that non-void functions have at least one return statement. if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue) { error(location, "function does not return a value:", "", function.getName().c_str()); - recover(); } - TIntermAggregate *aggregate = - intermediate.growAggregate(functionPrototype, functionBody, location); - intermediate.setAggregateOperator(aggregate, EOpFunction, location); - aggregate->setName(function.getMangledName().c_str()); - aggregate->setType(function.getReturnType()); - aggregate->setFunctionId(function.getUniqueId()); + TIntermAggregate *functionNode = new TIntermAggregate(EOpFunction); + functionNode->setLine(location); + + ASSERT(functionPrototype != nullptr); + functionNode->getSequence()->push_back(functionPrototype); + + if (functionBody == nullptr) + { + functionBody = new TIntermAggregate(EOpSequence); + functionBody->setLine(location); + } + functionNode->getSequence()->push_back(functionBody); + + functionNode->setName(function.getMangledName().c_str()); + functionNode->setType(function.getReturnType()); + functionNode->setFunctionId(function.getUniqueId()); symbolTable.pop(); - return aggregate; + return functionNode; } void TParseContext::parseFunctionPrototype(const TSourceLoc &location, @@ -2013,7 +2100,6 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, if (builtIn) { error(location, "built-in functions cannot be redefined", function->getName().c_str()); - recover(); } TFunction *prevDec = @@ -2027,7 +2113,6 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, { // Then this function already has a body. error(location, "function already has a body", function->getName().c_str()); - recover(); } prevDec->setDefined(); // @@ -2043,13 +2128,11 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, if (function->getParamCount() > 0) { error(location, "function cannot take any parameter(s)", function->getName().c_str()); - recover(); } if (function->getReturnType().getBasicType() != EbtVoid) { error(location, "", function->getReturnType().getBasicString(), "main function cannot return a value"); - recover(); } } @@ -2080,7 +2163,6 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, if (!symbolTable.declare(variable)) { error(location, "redefinition", variable->getName().c_str()); - recover(); paramNodes = intermediate.growAggregate( paramNodes, intermediate.addSymbol(0, "", *param.type, location), location); continue; @@ -2124,7 +2206,6 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF // Therefore overloading or redefining builtin functions is an error. error(location, "Name of a built-in function cannot be redeclared as function", function->getName().c_str()); - recover(); } else if (prevDec) { @@ -2132,7 +2213,6 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF { error(location, "overloaded functions must have the same return type", function->getReturnType().getBasicString()); - recover(); } for (size_t i = 0; i < prevDec->getParamCount(); ++i) { @@ -2141,7 +2221,6 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF { error(location, "overloaded functions must have the same parameter qualifiers", function->getParam(i).type->getQualifierString()); - recover(); } } } @@ -2155,7 +2234,6 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF if (!prevSym->isFunction()) { error(location, "redefinition", function->getName().c_str(), "function"); - recover(); } } else @@ -2186,18 +2264,14 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type, { error(location, "no qualifiers allowed for function return", getQualifierString(type.qualifier)); - recover(); } if (!type.layoutQualifier.isEmpty()) { error(location, "no qualifiers allowed for function return", "layout"); - recover(); } // make sure a sampler is not involved as well... - if (samplerErrorCheck(location, type, "samplers can't be function return values")) - { - recover(); - } + checkIsNotSampler(location, type.typeSpecifierNonArray, + "samplers can't be function return values"); if (mShaderVersion < 300) { // Array return values are forbidden, but there's also no valid syntax for declaring array @@ -2209,7 +2283,6 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type, // ESSL 1.00.17 section 6.1 Function Definitions error(location, "structures containing arrays can't be function return values", TType(type).getCompleteString().c_str()); - recover(); } } @@ -2220,154 +2293,25 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type, TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn) { TPublicType publicType = publicTypeIn; - if (publicType.isStructSpecifier) + if (publicType.isStructSpecifier()) { - error(publicType.line, "constructor can't be a structure definition", - getBasicString(publicType.type)); - recover(); + error(publicType.getLine(), "constructor can't be a structure definition", + getBasicString(publicType.getBasicType())); } TOperator op = EOpNull; - if (publicType.userDef) + if (publicType.getUserDef()) { op = EOpConstructStruct; } else { - switch (publicType.type) - { - case EbtFloat: - if (publicType.isMatrix()) - { - switch (publicType.getCols()) - { - case 2: - switch (publicType.getRows()) - { - case 2: - op = EOpConstructMat2; - break; - case 3: - op = EOpConstructMat2x3; - break; - case 4: - op = EOpConstructMat2x4; - break; - } - break; - case 3: - switch (publicType.getRows()) - { - case 2: - op = EOpConstructMat3x2; - break; - case 3: - op = EOpConstructMat3; - break; - case 4: - op = EOpConstructMat3x4; - break; - } - break; - case 4: - switch (publicType.getRows()) - { - case 2: - op = EOpConstructMat4x2; - break; - case 3: - op = EOpConstructMat4x3; - break; - case 4: - op = EOpConstructMat4; - break; - } - break; - } - } - else - { - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructFloat; - break; - case 2: - op = EOpConstructVec2; - break; - case 3: - op = EOpConstructVec3; - break; - case 4: - op = EOpConstructVec4; - break; - } - } - break; - - case EbtInt: - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructInt; - break; - case 2: - op = EOpConstructIVec2; - break; - case 3: - op = EOpConstructIVec3; - break; - case 4: - op = EOpConstructIVec4; - break; - } - break; - - case EbtUInt: - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructUInt; - break; - case 2: - op = EOpConstructUVec2; - break; - case 3: - op = EOpConstructUVec3; - break; - case 4: - op = EOpConstructUVec4; - break; - } - break; - - case EbtBool: - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructBool; - break; - case 2: - op = EOpConstructBVec2; - break; - case 3: - op = EOpConstructBVec3; - break; - case 4: - op = EOpConstructBVec4; - break; - } - break; - - default: - break; - } - + op = sh::TypeToConstructorOperator(TType(publicType)); if (op == EOpNull) { - error(publicType.line, "cannot construct this type", getBasicString(publicType.type)); - recover(); - publicType.type = EbtFloat; + error(publicType.getLine(), "cannot construct this type", + getBasicString(publicType.getBasicType())); + publicType.setBasicType(EbtFloat); op = EOpConstructFloat; } } @@ -2380,52 +2324,36 @@ TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn) // This function is used to test for the correctness of the parameters passed to various constructor // functions and also convert them to the right datatype if it is allowed and required. // -// Returns 0 for an error or the constructed node (aggregate or typed) for no error. +// Returns a node to add to the tree regardless of if an error was generated or not. // TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, - TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line) { - TIntermAggregate *constructor = arguments->getAsAggregate(); - ASSERT(constructor != nullptr); - - if (type->isArray()) + TType type = fnCall->getReturnType(); + if (type.isUnsizedArray()) { - // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of - // the array. - TIntermSequence *args = constructor->getSequence(); - for (size_t i = 0; i < args->size(); i++) - { - const TType &argType = (*args)[i]->getAsTyped()->getType(); - // It has already been checked that the argument is not an array. - ASSERT(!argType.isArray()); - if (!argType.sameElementType(*type)) - { - error(line, "Array constructor argument has an incorrect type", "Error"); - recover(); - return nullptr; - } - } + type.setArraySize(static_cast<unsigned int>(fnCall->getParamCount())); } - else if (op == EOpConstructStruct) + bool constType = true; + for (size_t i = 0; i < fnCall->getParamCount(); ++i) { - const TFieldList &fields = type->getStruct()->fields(); - TIntermSequence *args = constructor->getSequence(); - - for (size_t i = 0; i < fields.size(); i++) - { - if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type()) - { - error(line, "Structure constructor arguments do not match structure fields", - "Error"); - recover(); + const TConstParameter ¶m = fnCall->getParam(i); + if (param.type->getQualifier() != EvqConst) + constType = false; + } + if (constType) + type.setQualifier(EvqConst); - return 0; - } - } + if (!checkConstructorArguments(line, arguments, *fnCall, op, type)) + { + TIntermTyped *dummyNode = intermediate.setAggregateOperator(nullptr, op, line); + dummyNode->setType(type); + return dummyNode; } + TIntermAggregate *constructor = arguments->getAsAggregate(); + ASSERT(constructor != nullptr); // Turn the argument list itself into a constructor constructor->setOp(op); @@ -2433,17 +2361,19 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, ASSERT(constructor->isConstructor()); // Need to set type before setPrecisionFromChildren() because bool doesn't have precision. - constructor->setType(*type); + constructor->setType(type); // Structs should not be precision qualified, the individual members may be. // Built-in types on the other hand should be precision qualified. if (op != EOpConstructStruct) { constructor->setPrecisionFromChildren(); - type->setPrecision(constructor->getPrecision()); + type.setPrecision(constructor->getPrecision()); } - TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor); + constructor->setType(type); + + TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor, &mDiagnostics); if (constConstructor) { return constConstructor; @@ -2453,169 +2383,36 @@ TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, } // -// This function returns the tree representation for the vector field(s) being accessed from contant -// vector. -// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a -// contant node is returned, else an aggregate node is returned (for v.xy). The input to this -// function could either be the symbol node or it could be the intermediate tree representation of -// accessing fields in a constant structure or column of a constant matrix. -// -TIntermTyped *TParseContext::addConstVectorNode(TVectorFields &fields, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError) -{ - const TConstantUnion *unionArray = node->getUnionArrayPointer(); - ASSERT(unionArray); - - TConstantUnion *constArray = new TConstantUnion[fields.num]; - - for (int i = 0; i < fields.num; i++) - { - if (fields.offsets[i] >= node->getType().getNominalSize()) - { - std::stringstream extraInfoStream; - extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); - fields.offsets[i] = node->getType().getNominalSize() - 1; - } - - constArray[i] = unionArray[fields.offsets[i]]; - } - return intermediate.addConstantUnion(constArray, node->getType(), line); -} - -// -// This function returns the column being accessed from a constant matrix. The values are retrieved -// from the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). -// The input to the function could either be a symbol node (m[0] where m is a constant matrix)that -// represents a constant matrix or it could be the tree representation of the constant matrix -// (s.m1[0] where s is a constant structure) -// -TIntermTyped *TParseContext::addConstMatrixNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError) -{ - if (index >= node->getType().getCols()) - { - std::stringstream extraInfoStream; - extraInfoStream << "matrix field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); - index = node->getType().getCols() - 1; - } - - const TConstantUnion *unionArray = node->getUnionArrayPointer(); - int size = node->getType().getCols(); - return intermediate.addConstantUnion(&unionArray[size * index], node->getType(), line); -} - -// -// This function returns an element of an array accessed from a constant array. The values are -// retrieved from the symbol table and parse-tree is built for the type of the element. The input -// to the function could either be a symbol node (a[0] where a is a constant array)that represents a -// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a -// constant structure) -// -TIntermTyped *TParseContext::addConstArrayNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError) -{ - TType arrayElementType = node->getType(); - arrayElementType.clearArrayness(); - - if (index >= node->getType().getArraySize()) - { - std::stringstream extraInfoStream; - extraInfoStream << "array field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); - index = node->getType().getArraySize() - 1; - } - size_t arrayElementSize = arrayElementType.getObjectSize(); - const TConstantUnion *unionArray = node->getUnionArrayPointer(); - return intermediate.addConstantUnion(&unionArray[arrayElementSize * index], node->getType(), - line); -} - -// -// This function returns the value of a particular field inside a constant structure from the symbol -// table. -// If there is an embedded/nested struct, it appropriately calls addConstStructNested or -// addConstStructFromAggr function and returns the parse-tree with the values of the embedded/nested -// struct. -// -TIntermTyped *TParseContext::addConstStruct(const TString &identifier, - TIntermTyped *node, - const TSourceLoc &line) -{ - const TFieldList &fields = node->getType().getStruct()->fields(); - size_t instanceSize = 0; - - for (size_t index = 0; index < fields.size(); ++index) - { - if (fields[index]->name() == identifier) - { - break; - } - else - { - instanceSize += fields[index]->type()->getObjectSize(); - } - } - - TIntermTyped *typedNode; - TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); - if (tempConstantNode) - { - const TConstantUnion *constArray = tempConstantNode->getUnionArrayPointer(); - - // type will be changed in the calling function - typedNode = intermediate.addConstantUnion(constArray + instanceSize, - tempConstantNode->getType(), line); - } - else - { - error(line, "Cannot offset into the structure", "Error"); - recover(); - - return 0; - } - - return typedNode; -} - -// // Interface/uniform blocks // -TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualifier, - const TSourceLoc &nameLine, - const TString &blockName, - TFieldList *fieldList, - const TString *instanceName, - const TSourceLoc &instanceLine, - TIntermTyped *arrayIndex, - const TSourceLoc &arrayIndexLine) +TIntermAggregate *TParseContext::addInterfaceBlock( + const TTypeQualifierBuilder &typeQualifierBuilder, + const TSourceLoc &nameLine, + const TString &blockName, + TFieldList *fieldList, + const TString *instanceName, + const TSourceLoc &instanceLine, + TIntermTyped *arrayIndex, + const TSourceLoc &arrayIndexLine) { - if (reservedErrorCheck(nameLine, blockName)) - recover(); + checkIsNotReserved(nameLine, blockName); + + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics); if (typeQualifier.qualifier != EvqUniform) { error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "interface blocks must be uniform"); - recover(); } - TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier; - if (layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier)) + if (typeQualifier.invariant) { - recover(); + error(typeQualifier.line, "invalid qualifier on interface block member", "invariant"); } + TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier; + checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier); + if (blockLayoutQualifier.matrixPacking == EmpUnspecified) { blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking; @@ -2626,11 +2423,12 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif blockLayoutQualifier.blockStorage = mDefaultBlockStorage; } + checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier); + TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName); if (!symbolTable.declare(blockNameSymbol)) { error(nameLine, "redefinition", blockName.c_str(), "interface block name"); - recover(); } // check for sampler types and apply layout qualifiers @@ -2642,7 +2440,6 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif { error(field->line(), "unsupported type", fieldType->getBasicString(), "sampler types are not allowed in interface blocks"); - recover(); } const TQualifier qualifier = fieldType->getQualifier(); @@ -2654,22 +2451,22 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif default: error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier)); - recover(); break; } - // check layout qualifiers - TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier(); - if (layoutLocationErrorCheck(field->line(), fieldLayoutQualifier)) + if (fieldType->isInvariant()) { - recover(); + error(field->line(), "invalid qualifier on interface block member", "invariant"); } + // check layout qualifiers + TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier(); + checkLocationIsNotSpecified(field->line(), fieldLayoutQualifier); + if (fieldLayoutQualifier.blockStorage != EbsUnspecified) { error(field->line(), "invalid layout qualifier:", getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here"); - recover(); } if (fieldLayoutQualifier.matrixPacking == EmpUnspecified) @@ -2687,11 +2484,10 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif } // add array index - int arraySize = 0; - if (arrayIndex != NULL) + unsigned int arraySize = 0; + if (arrayIndex != nullptr) { - if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize)) - recover(); + arraySize = checkIsValidArraySize(arrayIndexLine, arrayIndex); } TInterfaceBlock *interfaceBlock = @@ -2720,14 +2516,12 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif { error(field->line(), "redefinition", field->name().c_str(), "interface block member name"); - recover(); } } } else { - if (reservedErrorCheck(instanceLine, *instanceName)) - recover(); + checkIsNotReserved(instanceLine, *instanceName); // add a symbol for this interface block TVariable *instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); @@ -2737,14 +2531,13 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif { error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name"); - recover(); } symbolId = instanceTypeDef->getUniqueId(); symbolName = instanceTypeDef->getName(); } - TIntermAggregate *aggregate = intermediate.makeAggregate( + TIntermAggregate *aggregate = TIntermediate::MakeAggregate( intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), nameLine); aggregate->setOp(EOpDeclaration); @@ -2753,7 +2546,7 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif return aggregate; } -bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier) +void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier) { ++mStructNestingLevel; @@ -2763,10 +2556,7 @@ bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString if (mStructNestingLevel > 1) { error(line, "", "Embedded struct definitions are not allowed"); - return true; } - - return false; } void TParseContext::exitStructDeclaration() @@ -2780,16 +2570,16 @@ const int kWebGLMaxStructNesting = 4; } // namespace -bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field) +void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field) { if (!IsWebGLBasedSpec(mShaderSpec)) { - return false; + return; } if (field.type()->getBasicType() != EbtStruct) { - return false; + return; } // We're already inside a structure definition at this point, so add @@ -2801,10 +2591,8 @@ bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting; std::string reason = reasonStream.str(); error(line, reason.c_str(), field.name().c_str(), ""); - return true; + return; } - - return false; } // @@ -2814,8 +2602,6 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression) { - TIntermTyped *indexedExpression = NULL; - if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector()) { if (baseExpression->getAsSymbolNode()) @@ -2827,7 +2613,11 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, { error(location, " left of '[' is not of type array, matrix, or vector ", "expression"); } - recover(); + + TConstantUnion *unionArray = new TConstantUnion[1]; + unionArray->setFConst(0.0f); + return intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), + location); } TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion(); @@ -2843,171 +2633,117 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, error( location, "", "[", "array indexes for interface blocks arrays must be constant integral expressions"); - recover(); } else if (baseExpression->getQualifier() == EvqFragmentOut) { error(location, "", "[", "array indexes for fragment outputs must be constant integral expressions"); - recover(); } else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData) { error(location, "", "[", "array index for gl_FragData must be constant zero"); - recover(); } } if (indexConstantUnion) { - // If the index is not qualified as constant, the behavior in the spec is undefined. This - // applies even if ANGLE has been able to constant fold it (ANGLE may constant fold - // expressions that are not constant expressions). The most compatible way to handle this - // case is to report a warning instead of an error and force the index to be in the - // correct range. + // If an out-of-range index is not qualified as constant, the behavior in the spec is + // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may + // constant fold expressions that are not constant expressions). The most compatible way to + // handle this case is to report a warning instead of an error and force the index to be in + // the correct range. bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst; int index = indexConstantUnion->getIConst(0); - if (index < 0) - { - std::stringstream infoStream; - infoStream << index; - std::string info = infoStream.str(); - outOfRangeError(outOfRangeIndexIsError, location, "negative index", info.c_str()); - index = 0; - } - TIntermConstantUnion *baseConstantUnion = baseExpression->getAsConstantUnion(); - if (baseConstantUnion) - { - if (baseExpression->isArray()) - { - // constant folding for array indexing - indexedExpression = - addConstArrayNode(index, baseConstantUnion, location, outOfRangeIndexIsError); - } - else if (baseExpression->isVector()) - { - // constant folding for vector indexing - TVectorFields fields; - fields.num = 1; - fields.offsets[0] = - index; // need to do it this way because v.xy sends fields integer array - indexedExpression = - addConstVectorNode(fields, baseConstantUnion, location, outOfRangeIndexIsError); - } - else if (baseExpression->isMatrix()) - { - // constant folding for matrix indexing - indexedExpression = - addConstMatrixNode(index, baseConstantUnion, location, outOfRangeIndexIsError); - } - } - else - { - int safeIndex = -1; - if (baseExpression->isArray()) + int safeIndex = -1; + + if (baseExpression->isArray()) + { + if (baseExpression->getQualifier() == EvqFragData && index > 0) { - if (baseExpression->getQualifier() == EvqFragData && index > 0) + if (mShaderSpec == SH_WEBGL2_SPEC) { - if (mShaderSpec == SH_WEBGL2_SPEC) - { - // Error has been already generated if index is not const. - if (indexExpression->getQualifier() == EvqConst) - { - error(location, "", "[", - "array index for gl_FragData must be constant zero"); - recover(); - } - safeIndex = 0; - } - else if (!isExtensionEnabled("GL_EXT_draw_buffers")) + // Error has been already generated if index is not const. + if (indexExpression->getQualifier() == EvqConst) { - outOfRangeError(outOfRangeIndexIsError, location, "", "[", - "array index for gl_FragData must be zero when " - "GL_EXT_draw_buffers is disabled"); - safeIndex = 0; + error(location, "", "[", + "array index for gl_FragData must be constant zero"); } + safeIndex = 0; } - // Only do generic out-of-range check if similar error hasn't already been reported. - if (safeIndex < 0 && index >= baseExpression->getType().getArraySize()) + else if (!isExtensionEnabled("GL_EXT_draw_buffers")) { - std::stringstream extraInfoStream; - extraInfoStream << "array index out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, location, "", "[", extraInfo.c_str()); - safeIndex = baseExpression->getType().getArraySize() - 1; + outOfRangeError(outOfRangeIndexIsError, location, "", "[", + "array index for gl_FragData must be zero when " + "GL_EXT_draw_buffers is disabled"); + safeIndex = 0; } } - else if ((baseExpression->isVector() || baseExpression->isMatrix()) && - baseExpression->getType().getNominalSize() <= index) - { - std::stringstream extraInfoStream; - extraInfoStream << "field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, location, "", "[", extraInfo.c_str()); - safeIndex = baseExpression->getType().getNominalSize() - 1; - } - - // Data of constant unions can't be changed, because it may be shared with other - // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new - // sanitized object. - if (safeIndex != -1) + // Only do generic out-of-range check if similar error hasn't already been reported. + if (safeIndex < 0) { - TConstantUnion *safeConstantUnion = new TConstantUnion(); - safeConstantUnion->setIConst(safeIndex); - indexConstantUnion->replaceConstantUnion(safeConstantUnion); + safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index, + baseExpression->getArraySize(), + "array index out of range", "[]"); } + } + else if (baseExpression->isMatrix()) + { + safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index, + baseExpression->getType().getCols(), + "matrix field selection out of range", "[]"); + } + else if (baseExpression->isVector()) + { + safeIndex = checkIndexOutOfRange(outOfRangeIndexIsError, location, index, + baseExpression->getType().getNominalSize(), + "vector field selection out of range", "[]"); + } - indexedExpression = - intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); + ASSERT(safeIndex >= 0); + // Data of constant unions can't be changed, because it may be shared with other + // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new + // sanitized object. + if (safeIndex != index) + { + TConstantUnion *safeConstantUnion = new TConstantUnion(); + safeConstantUnion->setIConst(safeIndex); + indexConstantUnion->replaceConstantUnion(safeConstantUnion); } - } - else - { - indexedExpression = - intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); - } - if (indexedExpression == 0) - { - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setFConst(0.0f); - indexedExpression = - intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location); - } - else if (baseExpression->isArray()) - { - TType indexedType = baseExpression->getType(); - indexedType.clearArrayness(); - indexedExpression->setType(indexedType); - } - else if (baseExpression->isMatrix()) - { - indexedExpression->setType(TType(baseExpression->getBasicType(), - baseExpression->getPrecision(), EvqTemporary, - static_cast<unsigned char>(baseExpression->getRows()))); - } - else if (baseExpression->isVector()) - { - indexedExpression->setType( - TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary)); + return intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location, + &mDiagnostics); } else { - indexedExpression->setType(baseExpression->getType()); + return intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location, + &mDiagnostics); } +} - if (baseExpression->getType().getQualifier() == EvqConst && - indexExpression->getType().getQualifier() == EvqConst) - { - indexedExpression->getTypePointer()->setQualifier(EvqConst); - } - else +int TParseContext::checkIndexOutOfRange(bool outOfRangeIndexIsError, + const TSourceLoc &location, + int index, + int arraySize, + const char *reason, + const char *token) +{ + if (index >= arraySize || index < 0) { - indexedExpression->getTypePointer()->setQualifier(EvqTemporary); + std::stringstream extraInfoStream; + extraInfoStream << "'" << index << "'"; + std::string extraInfo = extraInfoStream.str(); + outOfRangeError(outOfRangeIndexIsError, location, reason, token, extraInfo.c_str()); + if (index < 0) + { + return 0; + } + else + { + return arraySize - 1; + } } - - return indexedExpression; + return index; } TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, @@ -3015,12 +2751,10 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre const TString &fieldString, const TSourceLoc &fieldLocation) { - TIntermTyped *indexedExpression = NULL; - if (baseExpression->isArray()) { error(fieldLocation, "cannot apply dot operator to an array", "."); - recover(); + return baseExpression; } if (baseExpression->isVector()) @@ -3031,46 +2765,21 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre { fields.num = 1; fields.offsets[0] = 0; - recover(); } - if (baseExpression->getAsConstantUnion()) - { - // constant folding for vector fields - indexedExpression = addConstVectorNode(fields, baseExpression->getAsConstantUnion(), - fieldLocation, true); - } - else - { - TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation); - indexedExpression = - intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation); - } - if (indexedExpression == nullptr) - { - recover(); - indexedExpression = baseExpression; - } - else - { - // Note that the qualifier set here will be corrected later. - indexedExpression->setType(TType(baseExpression->getBasicType(), - baseExpression->getPrecision(), EvqTemporary, - (unsigned char)(fieldString).size())); - } + return TIntermediate::AddSwizzle(baseExpression, fields, dotLocation); } else if (baseExpression->getBasicType() == EbtStruct) { - bool fieldFound = false; const TFieldList &fields = baseExpression->getType().getStruct()->fields(); if (fields.empty()) { error(dotLocation, "structure has no fields", "Internal Error"); - recover(); - indexedExpression = baseExpression; + return baseExpression; } else { + bool fieldFound = false; unsigned int i; for (i = 0; i < fields.size(); ++i) { @@ -3082,50 +2791,29 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre } if (fieldFound) { - if (baseExpression->getAsConstantUnion()) - { - indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation); - if (indexedExpression == 0) - { - recover(); - indexedExpression = baseExpression; - } - else - { - indexedExpression->setType(*fields[i]->type()); - } - } - else - { - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setIConst(i); - TIntermTyped *index = intermediate.addConstantUnion( - unionArray, *fields[i]->type(), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, - index, dotLocation); - indexedExpression->setType(*fields[i]->type()); - } + TIntermTyped *index = TIntermTyped::CreateIndexNode(i); + index->setLine(fieldLocation); + return intermediate.addIndex(EOpIndexDirectStruct, baseExpression, index, + dotLocation, &mDiagnostics); } else { error(dotLocation, " no such field in structure", fieldString.c_str()); - recover(); - indexedExpression = baseExpression; + return baseExpression; } } } else if (baseExpression->isInterfaceBlock()) { - bool fieldFound = false; const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields(); if (fields.empty()) { error(dotLocation, "interface block has no fields", "Internal Error"); - recover(); - indexedExpression = baseExpression; + return baseExpression; } else { + bool fieldFound = false; unsigned int i; for (i = 0; i < fields.size(); ++i) { @@ -3137,19 +2825,15 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre } if (fieldFound) { - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setIConst(i); - TIntermTyped *index = - intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, - baseExpression, index, dotLocation); - indexedExpression->setType(*fields[i]->type()); + TIntermTyped *index = TIntermTyped::CreateIndexNode(i); + index->setLine(fieldLocation); + return intermediate.addIndex(EOpIndexDirectInterfaceBlock, baseExpression, index, + dotLocation, &mDiagnostics); } else { error(dotLocation, " no such field in interface block", fieldString.c_str()); - recover(); - indexedExpression = baseExpression; + return baseExpression; } } } @@ -3167,30 +2851,14 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre "side", fieldString.c_str()); } - recover(); - indexedExpression = baseExpression; - } - - if (baseExpression->getQualifier() == EvqConst) - { - indexedExpression->getTypePointer()->setQualifier(EvqConst); - } - else - { - indexedExpression->getTypePointer()->setQualifier(EvqTemporary); + return baseExpression; } - - return indexedExpression; } TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc &qualifierTypeLine) { - TLayoutQualifier qualifier; - - qualifier.location = -1; - qualifier.matrixPacking = EmpUnspecified; - qualifier.blockStorage = EbsUnspecified; + TLayoutQualifier qualifier = TLayoutQualifier::create(); if (qualifierType == "shared") { @@ -3216,139 +2884,119 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp { error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), "location requires an argument"); - recover(); } else { error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str()); - recover(); } return qualifier; } +void TParseContext::parseLocalSize(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine, + int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + size_t index, + sh::WorkGroupSize *localSize) +{ + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + if (intValue < 1) + { + std::string errorMessage = std::string(getWorkGroupSizeString(index)) + " must be positive"; + error(intValueLine, "out of range:", intValueString.c_str(), errorMessage.c_str()); + } + (*localSize)[index] = intValue; +} + TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc &qualifierTypeLine, - const TString &intValueString, int intValue, const TSourceLoc &intValueLine) { - TLayoutQualifier qualifier; + TLayoutQualifier qualifier = TLayoutQualifier::create(); - qualifier.location = -1; - qualifier.matrixPacking = EmpUnspecified; - qualifier.blockStorage = EbsUnspecified; + std::string intValueString = Str(intValue); - if (qualifierType != "location") - { - error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), - "only location may have arguments"); - recover(); - } - else + if (qualifierType == "location") { // must check that location is non-negative if (intValue < 0) { error(intValueLine, "out of range:", intValueString.c_str(), "location must be non-negative"); - recover(); } else { qualifier.location = intValue; + qualifier.locationsSpecified = 1; } } - - return qualifier; -} - -TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, - TLayoutQualifier rightQualifier) -{ - TLayoutQualifier joinedQualifier = leftQualifier; - - if (rightQualifier.location != -1) + else if (qualifierType == "local_size_x") + { + parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u, + &qualifier.localSize); + } + else if (qualifierType == "local_size_y") { - joinedQualifier.location = rightQualifier.location; + parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u, + &qualifier.localSize); } - if (rightQualifier.matrixPacking != EmpUnspecified) + else if (qualifierType == "local_size_z") { - joinedQualifier.matrixPacking = rightQualifier.matrixPacking; + parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u, + &qualifier.localSize); } - if (rightQualifier.blockStorage != EbsUnspecified) + else { - joinedQualifier.blockStorage = rightQualifier.blockStorage; + error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str()); } - return joinedQualifier; + return qualifier; } -TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, - TQualifier interpolationQualifier, - const TSourceLoc &storageLoc, - TQualifier storageQualifier) +TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc) { - TQualifier mergedQualifier = EvqSmoothIn; + return new TTypeQualifierBuilder( + new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc), + mShaderVersion); +} - if (storageQualifier == EvqFragmentIn) - { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqSmoothIn; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatIn; - else - UNREACHABLE(); - } - else if (storageQualifier == EvqCentroidIn) - { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqCentroidIn; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatIn; - else - UNREACHABLE(); - } - else if (storageQualifier == EvqVertexOut) - { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqSmoothOut; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatOut; - else - UNREACHABLE(); - } - else if (storageQualifier == EvqCentroidOut) - { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqCentroidOut; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatOut; - else - UNREACHABLE(); - } - else - { - error(interpolationLoc, - "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", - getInterpolationString(interpolationQualifier)); - recover(); +TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation) +{ + return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation, + &mDiagnostics); +} - mergedQualifier = storageQualifier; - } +TFieldList *TParseContext::addStructDeclaratorListWithQualifiers( + const TTypeQualifierBuilder &typeQualifierBuilder, + TPublicType *typeSpecifier, + TFieldList *fieldList) +{ + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(&mDiagnostics); - TPublicType type; - type.setBasic(EbtVoid, mergedQualifier, storageLoc); - return type; + typeSpecifier->qualifier = typeQualifier.qualifier; + typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier; + typeSpecifier->invariant = typeQualifier.invariant; + if (typeQualifier.precision != EbpUndefined) + { + typeSpecifier->precision = typeQualifier.precision; + } + return addStructDeclaratorList(*typeSpecifier, fieldList); } TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList) { - if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type)) - { - recover(); - } + checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision, + typeSpecifier.getBasicType()); + + checkIsNonVoid(typeSpecifier.getLine(), (*fieldList)[0]->name(), typeSpecifier.getBasicType()); + + checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier); for (unsigned int i = 0; i < fieldList->size(); ++i) { @@ -3356,59 +3004,51 @@ TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecif // Careful not to replace already known aspects of type, like array-ness // TType *type = (*fieldList)[i]->type(); - type->setBasicType(typeSpecifier.type); - type->setPrimarySize(typeSpecifier.primarySize); - type->setSecondarySize(typeSpecifier.secondarySize); + type->setBasicType(typeSpecifier.getBasicType()); + type->setPrimarySize(typeSpecifier.getPrimarySize()); + type->setSecondarySize(typeSpecifier.getSecondarySize()); type->setPrecision(typeSpecifier.precision); type->setQualifier(typeSpecifier.qualifier); type->setLayoutQualifier(typeSpecifier.layoutQualifier); + type->setInvariant(typeSpecifier.invariant); // don't allow arrays of arrays if (type->isArray()) { - if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier)) - recover(); + checkIsValidTypeForArray(typeSpecifier.getLine(), typeSpecifier); } if (typeSpecifier.array) - type->setArraySize(typeSpecifier.arraySize); - if (typeSpecifier.userDef) + type->setArraySize(static_cast<unsigned int>(typeSpecifier.arraySize)); + if (typeSpecifier.getUserDef()) { - type->setStruct(typeSpecifier.userDef->getStruct()); + type->setStruct(typeSpecifier.getUserDef()->getStruct()); } - if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) - { - recover(); - } + checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *(*fieldList)[i]); } return fieldList; } -TPublicType TParseContext::addStructure(const TSourceLoc &structLine, - const TSourceLoc &nameLine, - const TString *structName, - TFieldList *fieldList) +TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine, + const TSourceLoc &nameLine, + const TString *structName, + TFieldList *fieldList) { TStructure *structure = new TStructure(structName, fieldList); TType *structureType = new TType(structure); // Store a bool in the struct if we're at global scope, to allow us to // skip the local struct scoping workaround in HLSL. - structure->setUniqueId(TSymbolTable::nextUniqueId()); structure->setAtGlobalScope(symbolTable.atGlobalLevel()); if (!structName->empty()) { - if (reservedErrorCheck(nameLine, *structName)) - { - recover(); - } + checkIsNotReserved(nameLine, *structName); TVariable *userTypeDef = new TVariable(structName, *structureType, true); if (!symbolTable.declare(userTypeDef)) { error(nameLine, "redefinition", structName->c_str(), "struct"); - recover(); } } @@ -3425,18 +3065,23 @@ TPublicType TParseContext::addStructure(const TSourceLoc &structLine, default: error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier)); - recover(); break; } + if (field.type()->isInvariant()) + { + error(field.line(), "invalid qualifier on struct member", "invariant"); + } + + checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier()); } - TPublicType publicType; - publicType.setBasic(EbtStruct, EvqTemporary, structLine); - publicType.userDef = structureType; - publicType.isStructSpecifier = true; + TTypeSpecifierNonArray typeSpecifierNonArray; + typeSpecifierNonArray.initialize(EbtStruct, structLine); + typeSpecifierNonArray.userDef = structureType; + typeSpecifierNonArray.isStructSpecifier = true; exitStructDeclaration(); - return publicType; + return typeSpecifierNonArray; } TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, @@ -3449,7 +3094,6 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, { error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch"); - recover(); return nullptr; } @@ -3457,7 +3101,6 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, { if (!ValidateSwitch::validate(switchType, this, statementList, loc)) { - recover(); return nullptr; } } @@ -3466,7 +3109,6 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, if (node == nullptr) { error(loc, "erroneous switch statement", "switch"); - recover(); return nullptr; } return node; @@ -3477,20 +3119,17 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l if (mSwitchNestingLevel == 0) { error(loc, "case labels need to be inside switch statements", "case"); - recover(); return nullptr; } if (condition == nullptr) { error(loc, "case label must have a condition", "case"); - recover(); return nullptr; } if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) || condition->isMatrix() || condition->isArray() || condition->isVector()) { error(condition->getLine(), "case label must be a scalar integer", "case"); - recover(); } TIntermConstantUnion *conditionConst = condition->getAsConstantUnion(); // TODO(oetuaho@nvidia.com): Get rid of the conditionConst == nullptr check once all constant @@ -3499,13 +3138,11 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l if (condition->getQualifier() != EvqConst || conditionConst == nullptr) { error(condition->getLine(), "case label must be constant", "case"); - recover(); } TIntermCase *node = intermediate.addCase(condition, loc); if (node == nullptr) { error(loc, "erroneous case statement", "case"); - recover(); return nullptr; } return node; @@ -3516,14 +3153,12 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc) if (mSwitchNestingLevel == 0) { error(loc, "default labels need to be inside switch statements", "default"); - recover(); return nullptr; } TIntermCase *node = intermediate.addCase(nullptr, loc); if (node == nullptr) { error(loc, "erroneous default statement", "default"); - recover(); return nullptr; } return node; @@ -3562,7 +3197,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, case EOpNegative: case EOpPositive: if (child->getBasicType() == EbtStruct || child->getBasicType() == EbtBool || - child->isArray()) + child->isArray() || IsSampler(child->getBasicType())) { return nullptr; } @@ -3571,7 +3206,14 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, break; } - return intermediate.addUnaryMath(op, child, loc, funcReturnType); + TIntermUnary *node = new TIntermUnary(op, child); + node->setLine(loc); + + TIntermTyped *foldedNode = node->fold(&mDiagnostics); + if (foldedNode) + return foldedNode; + + return node; } TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) @@ -3580,7 +3222,6 @@ TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, con if (node == nullptr) { unaryOpError(loc, GetOperatorString(op), child->getCompleteString()); - recover(); return child; } return node; @@ -3590,8 +3231,7 @@ TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc) { - if (lValueErrorCheck(loc, GetOperatorString(op), child)) - recover(); + checkCanBeLValue(loc, GetOperatorString(op), child); return addUnaryMath(op, child, loc); } @@ -3600,6 +3240,28 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *right, const TSourceLoc &loc) { + if (left->getType().getStruct() || right->getType().getStruct()) + { + switch (op) + { + case EOpIndexDirectStruct: + ASSERT(left->getType().getStruct()); + break; + case EOpEqual: + case EOpNotEqual: + case EOpAssign: + case EOpInitialize: + if (left->getType() != right->getType()) + { + return false; + } + break; + default: + error(loc, "Invalid operation for structs", GetOperatorString(op)); + return false; + } + } + if (left->isArray() || right->isArray()) { if (mShaderVersion < 300) @@ -3673,8 +3335,10 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, return false; } - // Check that type sizes match exactly on ops that require that. - // Also check restrictions for structs that contain arrays or samplers. + // Check that: + // 1. Type sizes match exactly on ops that require that. + // 2. Restrictions for structs that contain arrays or samplers are respected. + // 3. Arithmetic op type dimensionality restrictions for ops other than multiply are respected. switch (op) { case EOpAssign: @@ -3707,6 +3371,48 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, { return false; } + break; + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpIMod: + case EOpBitShiftLeft: + case EOpBitShiftRight: + case EOpBitwiseAnd: + case EOpBitwiseXor: + case EOpBitwiseOr: + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + case EOpIModAssign: + case EOpBitShiftLeftAssign: + case EOpBitShiftRightAssign: + case EOpBitwiseAndAssign: + case EOpBitwiseXorAssign: + case EOpBitwiseOrAssign: + if ((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix())) + { + return false; + } + + // Are the sizes compatible? + if (left->getNominalSize() != right->getNominalSize() || + left->getSecondarySize() != right->getSecondarySize()) + { + // If the nominal sizes of operands do not match: + // One of them must be a scalar. + if (!left->isScalar() && !right->isScalar()) + return false; + + // In the case of compound assignment other than multiply-assign, + // the right side needs to be a scalar. Otherwise a vector/matrix + // would be assigned to a scalar. A scalar can't be shifted by a + // vector either. + if (!right->isScalar() && + (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight)) + return false; + } + break; default: break; } @@ -3714,6 +3420,49 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, return true; } +bool TParseContext::isMultiplicationTypeCombinationValid(TOperator op, + const TType &left, + const TType &right) +{ + switch (op) + { + case EOpMul: + case EOpMulAssign: + return left.getNominalSize() == right.getNominalSize() && + left.getSecondarySize() == right.getSecondarySize(); + case EOpVectorTimesScalar: + return true; + case EOpVectorTimesScalarAssign: + ASSERT(!left.isMatrix() && !right.isMatrix()); + return left.isVector() && !right.isVector(); + case EOpVectorTimesMatrix: + return left.getNominalSize() == right.getRows(); + case EOpVectorTimesMatrixAssign: + ASSERT(!left.isMatrix() && right.isMatrix()); + return left.isVector() && left.getNominalSize() == right.getRows() && + left.getNominalSize() == right.getCols(); + case EOpMatrixTimesVector: + return left.getCols() == right.getNominalSize(); + case EOpMatrixTimesScalar: + return true; + case EOpMatrixTimesScalarAssign: + ASSERT(left.isMatrix() && !right.isMatrix()); + return !right.isVector(); + case EOpMatrixTimesMatrix: + return left.getCols() == right.getRows(); + case EOpMatrixTimesMatrixAssign: + ASSERT(left.isMatrix() && right.isMatrix()); + // We need to check two things: + // 1. The matrix multiplication step is valid. + // 2. The result will have the same number of columns as the lvalue. + return left.getCols() == right.getRows() && left.getCols() == right.getCols(); + + default: + UNREACHABLE(); + return false; + } +} + TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, @@ -3731,8 +3480,9 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: - ASSERT(!left->isArray() && !right->isArray()); - if (left->isMatrix() || left->isVector() || left->getBasicType() == EbtStruct) + ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() && + !right->getType().getStruct()); + if (left->isMatrix() || left->isVector()) { return nullptr; } @@ -3740,7 +3490,8 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, case EOpLogicalOr: case EOpLogicalXor: case EOpLogicalAnd: - ASSERT(!left->isArray() && !right->isArray()); + ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() && + !right->getType().getStruct()); if (left->getBasicType() != EbtBool || left->isMatrix() || left->isVector()) { return nullptr; @@ -3750,28 +3501,44 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, case EOpSub: case EOpDiv: case EOpMul: - ASSERT(!left->isArray() && !right->isArray()); - if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) + ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() && + !right->getType().getStruct()); + if (left->getBasicType() == EbtBool) { return nullptr; } break; case EOpIMod: - ASSERT(!left->isArray() && !right->isArray()); + ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() && + !right->getType().getStruct()); // Note that this is only for the % operator, not for mod() - if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || - left->getBasicType() == EbtFloat) + if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) { return nullptr; } break; - // Note that for bitwise ops, type checking is done in promote() to - // share code between ops and compound assignment default: break; } - return intermediate.addBinaryMath(op, left, right, loc); + if (op == EOpMul) + { + op = TIntermBinary::GetMulOpBasedOnOperands(left->getType(), right->getType()); + if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType())) + { + return nullptr; + } + } + + TIntermBinary *node = new TIntermBinary(op, left, right); + node->setLine(loc); + + // See if we can fold constants. + TIntermTyped *foldedNode = node->fold(&mDiagnostics); + if (foldedNode) + return foldedNode; + + return node; } TIntermTyped *TParseContext::addBinaryMath(TOperator op, @@ -3784,7 +3551,6 @@ TIntermTyped *TParseContext::addBinaryMath(TOperator op, { binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString()); - recover(); return left; } return node; @@ -3800,7 +3566,6 @@ TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, { binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString()); - recover(); TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setBConst(false); return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @@ -3816,7 +3581,18 @@ TIntermTyped *TParseContext::createAssign(TOperator op, { if (binaryOpCommonCheck(op, left, right, loc)) { - return intermediate.addAssign(op, left, right, loc); + if (op == EOpMulAssign) + { + op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType()); + if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType())) + { + return nullptr; + } + } + TIntermBinary *node = new TIntermBinary(op, left, right); + node->setLine(loc); + + return node; } return nullptr; } @@ -3830,7 +3606,6 @@ TIntermTyped *TParseContext::addAssign(TOperator op, if (node == nullptr) { assignError(loc, "assign", left->getCompleteString(), right->getCompleteString()); - recover(); return left; } return node; @@ -3840,6 +3615,18 @@ TIntermTyped *TParseContext::addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc) { + // WebGL2 section 5.26, the following results in an error: + // "Sequence operator applied to void, arrays, or structs containing arrays" + if (mShaderSpec == SH_WEBGL2_SPEC && (left->isArray() || left->getBasicType() == EbtVoid || + left->getType().isStructureContainingArrays() || + right->isArray() || right->getBasicType() == EbtVoid || + right->getType().isStructureContainingArrays())) + { + error(loc, + "sequence operator is not allowed for void, arrays, or structs containing arrays", + ","); + } + return intermediate.addComma(left, right, loc, mShaderVersion); } @@ -3851,21 +3638,18 @@ TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) if (mLoopNestingLevel <= 0) { error(loc, "continue statement only allowed in loops", ""); - recover(); } break; case EOpBreak: if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0) { error(loc, "break statement only allowed in loops and switch statements", ""); - recover(); } break; case EOpReturn: if (mCurrentFunctionType->getBasicType() != EbtVoid) { error(loc, "non-void function must return a value", "return"); - recover(); } break; default: @@ -3884,12 +3668,10 @@ TIntermBranch *TParseContext::addBranch(TOperator op, if (mCurrentFunctionType->getBasicType() == EbtVoid) { error(loc, "void function cannot return a value", "return"); - recover(); } else if (*mCurrentFunctionType != returnValue->getType()) { error(loc, "function return is not matching type:", "return"); - recover(); } return intermediate.addBranch(op, returnValue, loc); } @@ -3923,7 +3705,6 @@ void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall) TString unmangledName = TFunction::unmangleName(name); error(functionCall->getLine(), "Texture offset must be a constant expression", unmangledName.c_str()); - recover(); } else { @@ -3940,7 +3721,6 @@ void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall) std::string token = tokenStream.str(); error(offset->getLine(), "Texture offset value out of valid range", token.c_str()); - recover(); } } } @@ -3965,17 +3745,14 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, if (fnCall->getName() != "length") { error(loc, "invalid method", fnCall->getName().c_str()); - recover(); } else if (paramNode != nullptr) { error(loc, "method takes no parameters", "length"); - recover(); } else if (typedThis == nullptr || !typedThis->isArray()) { error(loc, "length can only be called on arrays", "length"); - recover(); } else { @@ -3993,7 +3770,6 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, // length method applied". error(loc, "length can only be called on array names, not on array expressions", "length"); - recover(); } } unionArray->setIConst(arraySize); @@ -4002,26 +3778,8 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, } else if (op != EOpNull) { - // // Then this should be a constructor. - // Don't go through the symbol table for constructors. - // Their parameters will be verified algorithmically. - // - TType type(EbtVoid, EbpUndefined); // use this to get the type back - if (!constructorErrorCheck(loc, paramNode, *fnCall, op, &type)) - { - // - // It's a constructor, of type 'type'. - // - callNode = addConstructor(paramNode, &type, op, fnCall, loc); - } - - if (callNode == nullptr) - { - recover(); - callNode = intermediate.setAggregateOperator(nullptr, op, loc); - } - callNode->setType(type); + callNode = addConstructor(paramNode, op, fnCall, loc); } else { @@ -4036,10 +3794,9 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, // // A declared function. // - if (builtIn && !fnCandidate->getExtension().empty() && - extensionErrorCheck(loc, fnCandidate->getExtension())) + if (builtIn && !fnCandidate->getExtension().empty()) { - recover(); + checkCanUseExtension(loc, fnCandidate->getExtension()); } op = fnCandidate->getBuiltInOp(); if (builtIn && op != EOpNull) @@ -4085,7 +3842,8 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, // See if we can constant fold a built-in. Note that this may be possible even // if it is not const-qualified. - TIntermTyped *foldedNode = intermediate.foldAggregateBuiltIn(aggregate); + TIntermTyped *foldedNode = + intermediate.foldAggregateBuiltIn(aggregate, &mDiagnostics); if (foldedNode) { callNode = foldedNode; @@ -4134,36 +3892,41 @@ TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, unionArray->setFConst(0.0f); callNode = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), loc); - recover(); } } return callNode; } TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, - TIntermTyped *trueBlock, - TIntermTyped *falseBlock, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression, const TSourceLoc &loc) { - if (boolErrorCheck(loc, cond)) - recover(); + checkIsScalarBool(loc, cond); - if (trueBlock->getType() != falseBlock->getType()) + if (trueExpression->getType() != falseExpression->getType()) { - binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString()); - recover(); - return falseBlock; + binaryOpError(loc, ":", trueExpression->getCompleteString(), + falseExpression->getCompleteString()); + return falseExpression; } // ESSL1 sections 5.2 and 5.7: // ESSL3 section 5.7: // Ternary operator is not among the operators allowed for structures/arrays. - if (trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct) + if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct) { error(loc, "ternary operator is not allowed for structures or arrays", ":"); - recover(); - return falseBlock; + return falseExpression; } - return intermediate.addSelection(cond, trueBlock, falseBlock, loc); + // WebGL2 section 5.26, the following results in an error: + // "Ternary operator applied to void, arrays, or structs containing arrays" + if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid) + { + error(loc, "ternary operator is not allowed for void", ":"); + return falseExpression; + } + + return TIntermediate::AddTernarySelection(cond, trueExpression, falseExpression, loc); } // diff --git a/chromium/third_party/angle/src/compiler/translator/ParseContext.h b/chromium/third_party/angle/src/compiler/translator/ParseContext.h index c511330721f..c2c4bf2b4ac 100644 --- a/chromium/third_party/angle/src/compiler/translator/ParseContext.h +++ b/chromium/third_party/angle/src/compiler/translator/ParseContext.h @@ -11,6 +11,7 @@ #include "compiler/translator/DirectiveHandler.h" #include "compiler/translator/Intermediate.h" #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/QualifierTypes.h" #include "compiler/preprocessor/Preprocessor.h" struct TMatrixFields @@ -30,18 +31,18 @@ class TParseContext : angle::NonCopyable public: TParseContext(TSymbolTable &symt, TExtensionBehavior &ext, - TIntermediate &interm, sh::GLenum type, ShShaderSpec spec, - int options, + ShCompileOptions options, bool checksPrecErrors, TInfoSink &is, const ShBuiltInResources &resources) - : intermediate(interm), + : intermediate(), symbolTable(symt), mDeferredSingleDeclarationErrorCheck(false), mShaderType(type), mShaderSpec(spec), + mCompileOptions(options), mShaderVersion(100), mTreeRoot(nullptr), mLoopNestingLevel(0), @@ -65,8 +66,11 @@ class TParseContext : angle::NonCopyable mUsesFragColor(false), mUsesSecondaryOutputs(false), mMinProgramTexelOffset(resources.MinProgramTexelOffset), - mMaxProgramTexelOffset(resources.MaxProgramTexelOffset) + mMaxProgramTexelOffset(resources.MaxProgramTexelOffset), + mComputeShaderLocalSizeDeclared(false), + mDeclaringFunction(false) { + mComputeShaderLocalSize.fill(-1); } const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; } @@ -90,7 +94,6 @@ class TParseContext : angle::NonCopyable const char *token, const char *extraInfo = ""); - void recover(); TIntermNode *getTreeRoot() const { return mTreeRoot; } void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; } @@ -114,6 +117,15 @@ class TParseContext : angle::NonCopyable void incrSwitchNestingLevel() { ++mSwitchNestingLevel; } void decrSwitchNestingLevel() { --mSwitchNestingLevel; } + bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } + sh::WorkGroupSize getComputeShaderLocalSize() const; + + void enterFunctionDeclaration() { mDeclaringFunction = true; } + + void exitFunctionDeclaration() { mDeclaringFunction = false; } + + bool declaringFunction() const { return mDeclaringFunction; } + // This method is guaranteed to succeed, even if no variable with 'name' exists. const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol); TIntermTyped *parseVariableIdentifier(const TSourceLoc &location, @@ -122,38 +134,59 @@ class TParseContext : angle::NonCopyable bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line); - bool reservedErrorCheck(const TSourceLoc &line, const TString &identifier); void assignError(const TSourceLoc &line, const char *op, TString left, TString right); void unaryOpError(const TSourceLoc &line, const char *op, TString operand); void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right); - bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type); - bool lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped*); - bool constErrorCheck(TIntermTyped *node); - bool integerErrorCheck(TIntermTyped *node, const char *token); - bool globalErrorCheck(const TSourceLoc &line, bool global, const char *token); - bool constructorErrorCheck(const TSourceLoc &line, - TIntermNode *argumentsNode, - TFunction &function, - TOperator op, - TType *type); - bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size); - bool arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type); - bool arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type); - bool voidErrorCheck(const TSourceLoc &line, const TString &identifier, const TBasicType &type); - bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*); - bool boolErrorCheck(const TSourceLoc&, const TPublicType&); - bool samplerErrorCheck(const TSourceLoc &line, const TPublicType &pType, const char *reason); - bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType); - bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType &type); - bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType *type); - bool extensionErrorCheck(const TSourceLoc &line, const TString&); - bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation); - bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier); - bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *); - void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation); - void es3InputOutputTypeCheck(const TQualifier qualifier, - const TPublicType &type, - const TSourceLoc &qualifierLocation); + + // Check functions - the ones that return bool return false if an error was generated. + + bool checkIsNotReserved(const TSourceLoc &line, const TString &identifier); + void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type); + bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node); + void checkIsConst(TIntermTyped *node); + void checkIsScalarInteger(TIntermTyped *node, const char *token); + bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token); + bool checkConstructorArguments(const TSourceLoc &line, + TIntermNode *argumentsNode, + const TFunction &function, + TOperator op, + const TType &type); + + // Returns a sanitized array size to use (the size is at least 1). + unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr); + bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier); + bool checkIsValidTypeForArray(const TSourceLoc &line, const TPublicType &elementType); + bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type); + void checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type); + void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType); + bool checkIsNotSampler(const TSourceLoc &line, + const TTypeSpecifierNonArray &pType, + const char *reason); + void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType); + void checkLocationIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier); + void checkOutParameterIsNotSampler(const TSourceLoc &line, + TQualifier qualifier, + const TType &type); + void checkIsParameterQualifierValid(const TSourceLoc &line, + const TTypeQualifierBuilder &typeQualifierBuilder, + TType *type); + bool checkCanUseExtension(const TSourceLoc &line, const TString &extension); + void singleDeclarationErrorCheck(const TPublicType &publicType, + const TSourceLoc &identifierLocation); + void checkLayoutQualifierSupported(const TSourceLoc &location, + const TString &layoutQualifierName, + int versionRequired); + bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier); + + void functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); + void checkInvariantVariableQualifier(bool invariant, + const TQualifier qualifier, + const TSourceLoc &invariantLocation); + void checkInputOutputTypeIsValidES3(const TQualifier qualifier, + const TPublicType &type, + const TSourceLoc &qualifierLocation); const TPragma &pragma() const { return mDirectiveHandler.pragma(); } const TExtensionBehavior &extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); } @@ -171,9 +204,7 @@ class TParseContext : angle::NonCopyable TIntermTyped *initializer, TIntermNode **intermNode); - TPublicType addFullySpecifiedType(TQualifier qualifier, - bool invariant, - TLayoutQualifier layoutQualifier, + TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, const TPublicType &typeSpecifier); TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, @@ -200,7 +231,7 @@ class TParseContext : angle::NonCopyable const TSourceLoc &initLocation, TIntermTyped *initializer); - TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, + TIntermAggregate *parseInvariantDeclaration(const TTypeQualifierBuilder &typeQualifierBuilder, const TSourceLoc &identifierLoc, const TString *identifier, const TSymbol *symbol); @@ -232,7 +263,7 @@ class TParseContext : angle::NonCopyable const TSourceLoc &initLocation, TIntermTyped *initializer); - void parseGlobalLayoutQualifier(const TPublicType &typeQualifier); + void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder); TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function, const TSourceLoc &location); TIntermAggregate *addFunctionDefinition(const TFunction &function, @@ -249,24 +280,10 @@ class TParseContext : angle::NonCopyable const TSourceLoc &location); TFunction *addConstructorFunc(const TPublicType &publicType); TIntermTyped *addConstructor(TIntermNode *arguments, - TType *type, TOperator op, TFunction *fnCall, const TSourceLoc &line); - TIntermTyped *addConstVectorNode(TVectorFields &fields, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError); - TIntermTyped *addConstMatrixNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError); - TIntermTyped *addConstArrayNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError); - TIntermTyped *addConstStruct( - const TString &identifier, TIntermTyped *node, const TSourceLoc& line); + TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc& location, TIntermTyped *indexExpression); @@ -275,39 +292,48 @@ class TParseContext : angle::NonCopyable const TString &fieldString, const TSourceLoc &fieldLocation); + TFieldList *addStructDeclaratorListWithQualifiers( + const TTypeQualifierBuilder &typeQualifierBuilder, + TPublicType *typeSpecifier, + TFieldList *fieldList); TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList); - TPublicType addStructure(const TSourceLoc &structLine, - const TSourceLoc &nameLine, - const TString *structName, - TFieldList *fieldList); + TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine, + const TSourceLoc &nameLine, + const TString *structName, + TFieldList *fieldList); - TIntermAggregate* addInterfaceBlock(const TPublicType &typeQualifier, + TIntermAggregate *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder, const TSourceLoc &nameLine, const TString &blockName, TFieldList *fieldList, const TString *instanceName, const TSourceLoc &instanceLine, TIntermTyped *arrayIndex, - const TSourceLoc& arrayIndexLine); - + const TSourceLoc &arrayIndexLine); + + void parseLocalSize(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine, + int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + size_t index, + sh::WorkGroupSize *localSize); TLayoutQualifier parseLayoutQualifier( const TString &qualifierType, const TSourceLoc &qualifierTypeLine); TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc &qualifierTypeLine, - const TString &intValueString, int intValue, const TSourceLoc &intValueLine); - TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier); - TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, - const TSourceLoc &storageLoc, TQualifier storageQualifier); + TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc); + TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation); // Performs an error check for embedded struct declarations. - // Returns true if an error was raised due to the declaration of - // this struct. - bool enterStructDeclaration(const TSourceLoc &line, const TString &identifier); + void enterStructDeclaration(const TSourceLoc &line, const TString &identifier); void exitStructDeclaration(); - bool structNestingErrorCheck(const TSourceLoc &line, const TField &field); + void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field); TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc); TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc); @@ -334,17 +360,35 @@ class TParseContext : angle::NonCopyable const TSourceLoc &loc, bool *fatalError); - TIntermTyped *addTernarySelection( - TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line); + TIntermTyped *addTernarySelection(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression, + const TSourceLoc &line); // TODO(jmadill): make these private - TIntermediate &intermediate; // to hold and build a parse tree + TIntermediate intermediate; // to build a parse tree TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed private: + // Returns a clamped index. + int checkIndexOutOfRange(bool outOfRangeIndexIsError, + const TSourceLoc &location, + int index, + int arraySize, + const char *reason, + const char *token); + bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable); - bool nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type); + void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, + const TString &identifier, + TPublicType *type); + + bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation, + const TPublicType &elementType); + + // Assumes that multiplication op has already been set based on the types. + bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right); TIntermTyped *addBinaryMathInternal( TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); @@ -363,15 +407,18 @@ class TParseContext : angle::NonCopyable bool mDeferredSingleDeclarationErrorCheck; sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack) - ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. + ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. + ShCompileOptions mCompileOptions; // Options passed to TCompiler int mShaderVersion; - TIntermNode *mTreeRoot; // root of parse tree being created + TIntermNode *mTreeRoot; // root of parse tree being created int mLoopNestingLevel; // 0 if outside all loops - int mStructNestingLevel; // incremented while parsing a struct declaration + int mStructNestingLevel; // incremented while parsing a struct declaration int mSwitchNestingLevel; // 0 if outside all switch statements - const TType *mCurrentFunctionType; // the return type of the function that's currently being parsed + const TType + *mCurrentFunctionType; // the return type of the function that's currently being parsed bool mFunctionReturnsValue; // true if a non-void function has a return - bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. + bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared + // without precision, explicit or implicit. bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling // ESSL1. TLayoutMatrixPacking mDefaultMatrixPacking; @@ -387,6 +434,12 @@ class TParseContext : angle::NonCopyable // gl_Secondary FragColor or both. int mMinProgramTexelOffset; int mMaxProgramTexelOffset; + + // keep track of local group size declared in layout. It should be declared only once. + bool mComputeShaderLocalSizeDeclared; + sh::WorkGroupSize mComputeShaderLocalSize; + // keeps track whether we are declaring / defining a function + bool mDeclaringFunction; }; int PaParseStrings( diff --git a/chromium/third_party/angle/src/compiler/translator/PoolAlloc.cpp b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.cpp index 27e1c06b5b8..3b44afe3358 100644 --- a/chromium/third_party/angle/src/compiler/translator/PoolAlloc.cpp +++ b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.cpp @@ -50,29 +50,18 @@ void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator) // Implement the functionality of the TPoolAllocator class, which // is documented in PoolAlloc.h. // -TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : - pageSize(growthIncrement), - alignment(allocationAlignment), - freeList(0), - inUseList(0), - numCalls(0), - totalBytes(0), - mLocked(false) +TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) + : alignment(allocationAlignment), +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + pageSize(growthIncrement), + freeList(0), + inUseList(0), + numCalls(0), + totalBytes(0), +#endif + mLocked(false) { // - // Don't allow page sizes we know are smaller than all common - // OS page sizes. - // - if (pageSize < 4*1024) - pageSize = 4*1024; - - // - // A large currentPageOffset indicates a new page needs to - // be obtained to allocate memory. - // - currentPageOffset = pageSize; - - // // Adjust alignment to be at least pointer aligned and // power of 2. // @@ -86,6 +75,20 @@ TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : alignment = a; alignmentMask = a - 1; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + // + // Don't allow page sizes we know are smaller than all common + // OS page sizes. + // + if (pageSize < 4 * 1024) + pageSize = 4 * 1024; + + // + // A large currentPageOffset indicates a new page needs to + // be obtained to allocate memory. + // + currentPageOffset = pageSize; + // // Align header skip // @@ -93,10 +96,14 @@ TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : if (headerSkip < sizeof(tHeader)) { headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask; } +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif } TPoolAllocator::~TPoolAllocator() { +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) while (inUseList) { tHeader* next = inUseList->nextPage; inUseList->~tHeader(); @@ -113,6 +120,16 @@ TPoolAllocator::~TPoolAllocator() delete [] reinterpret_cast<char*>(freeList); freeList = next; } +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + for (auto &allocs : mStack) + { + for (auto alloc : allocs) + { + free(alloc); + } + } + mStack.clear(); +#endif } // Support MSVC++ 6.0 @@ -153,14 +170,18 @@ void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, co void TPoolAllocator::push() { +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) tAllocState state = { currentPageOffset, inUseList }; - stack.push_back(state); - + mStack.push_back(state); + // // Indicate there is no current page to allocate from. // currentPageOffset = pageSize; +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif } // @@ -172,11 +193,12 @@ void TPoolAllocator::push() // void TPoolAllocator::pop() { - if (stack.size() < 1) + if (mStack.size() < 1) return; - tHeader* page = stack.back().page; - currentPageOffset = stack.back().offset; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + tHeader *page = mStack.back().page; + currentPageOffset = mStack.back().offset; while (inUseList != page) { // invoke destructor to free allocation list @@ -192,7 +214,14 @@ void TPoolAllocator::pop() inUseList = nextInUse; } - stack.pop_back(); + mStack.pop_back(); +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + for (auto &alloc : mStack.back()) + { + free(alloc); + } + mStack.pop_back(); +#endif } // @@ -201,7 +230,7 @@ void TPoolAllocator::pop() // void TPoolAllocator::popAll() { - while (stack.size() > 0) + while (mStack.size() > 0) pop(); } @@ -209,6 +238,7 @@ void* TPoolAllocator::allocate(size_t numBytes) { ASSERT(!mLocked); +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) // // Just keep some interesting statistics. // @@ -285,6 +315,14 @@ void* TPoolAllocator::allocate(size_t numBytes) currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask; return initializeAllocation(inUseList, ret, numBytes); +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + void *alloc = malloc(numBytes + alignmentMask); + mStack.back().push_back(alloc); + + intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc); + intAlloc = (intAlloc + alignmentMask) & ~alignmentMask; + return reinterpret_cast<void *>(intAlloc); +#endif } void TPoolAllocator::lock() diff --git a/chromium/third_party/angle/src/compiler/translator/PoolAlloc.h b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.h index 026e7a5c110..f15b3e05d84 100644 --- a/chromium/third_party/angle/src/compiler/translator/PoolAlloc.h +++ b/chromium/third_party/angle/src/compiler/translator/PoolAlloc.h @@ -157,7 +157,12 @@ public: void lock(); void unlock(); -protected: + private: + size_t alignment; // all returned allocations will be aligned at + // this granularity, which will be a power of 2 + size_t alignmentMask; + +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) friend struct tHeader; struct tHeader { @@ -200,20 +205,21 @@ protected: } size_t pageSize; // granularity of allocation from the OS - size_t alignment; // all returned allocations will be aligned at - // this granularity, which will be a power of 2 - size_t alignmentMask; size_t headerSkip; // amount of memory to skip to make room for the // header (basically, size of header, rounded // up to make it aligned size_t currentPageOffset; // next offset in top of inUseList to allocate from tHeader* freeList; // list of popped memory tHeader* inUseList; // list of all memory currently being used - tAllocStack stack; // stack of where to allocate from, to partition pool + tAllocStack mStack; // stack of where to allocate from, to partition pool int numCalls; // just an interesting statistic size_t totalBytes; // just an interesting statistic -private: + +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + std::vector<std::vector<void *>> mStack; +#endif + TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor bool mLocked; diff --git a/chromium/third_party/angle/src/compiler/translator/PruneEmptyDeclarations.cpp b/chromium/third_party/angle/src/compiler/translator/PruneEmptyDeclarations.cpp index ef62dbfce71..8cbeb7dee1f 100644 --- a/chromium/third_party/angle/src/compiler/translator/PruneEmptyDeclarations.cpp +++ b/chromium/third_party/angle/src/compiler/translator/PruneEmptyDeclarations.cpp @@ -66,6 +66,27 @@ bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *no ASSERT(parentAgg != nullptr); mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, emptyReplacement)); } + else if (sym->getType().getQualifier() != EvqGlobal && + sym->getType().getQualifier() != EvqTemporary) + { + // We've hit an empty struct declaration with a qualifier, for example like + // this: + // const struct a { int i; }; + // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so + // we convert the declaration to a regular struct declaration. This is okay, + // since ESSL 1.00 spec section 4.1.8 says about structs that "The optional + // qualifiers only apply to any declarators, and are not part of the type being + // defined for name." + + if (mInGlobalScope) + { + sym->getTypePointer()->setQualifier(EvqGlobal); + } + else + { + sym->getTypePointer()->setQualifier(EvqTemporary); + } + } } } return false; diff --git a/chromium/third_party/angle/src/compiler/translator/QualifierTypes.cpp b/chromium/third_party/angle/src/compiler/translator/QualifierTypes.cpp new file mode 100644 index 00000000000..30d8c4eed08 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/QualifierTypes.cpp @@ -0,0 +1,646 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/QualifierTypes.h" + +#include "compiler/translator/Diagnostics.h" + +#include <algorithm> + +namespace sh +{ +TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation, + TDiagnostics *diagnostics) +{ + TLayoutQualifier joinedQualifier = leftQualifier; + + if (rightQualifier.location != -1) + { + joinedQualifier.location = rightQualifier.location; + ++joinedQualifier.locationsSpecified; + } + if (rightQualifier.matrixPacking != EmpUnspecified) + { + joinedQualifier.matrixPacking = rightQualifier.matrixPacking; + } + if (rightQualifier.blockStorage != EbsUnspecified) + { + joinedQualifier.blockStorage = rightQualifier.blockStorage; + } + + for (size_t i = 0u; i < rightQualifier.localSize.size(); ++i) + { + if (rightQualifier.localSize[i] != -1) + { + if (joinedQualifier.localSize[i] != -1 && + joinedQualifier.localSize[i] != rightQualifier.localSize[i]) + { + diagnostics->error(rightQualifierLocation, + "Cannot have multiple different work group size specifiers", + getWorkGroupSizeString(i), ""); + } + joinedQualifier.localSize[i] = rightQualifier.localSize[i]; + } + } + + return joinedQualifier; +} +} // namespace sh + +namespace +{ + +// GLSL ES 3.10 does not impose a strict order on type qualifiers and allows multiple layout +// declarations. +// GLSL ES 3.10 Revision 4, 4.10 Order of Qualification +bool AreTypeQualifierChecksRelaxed(int shaderVersion) +{ + return shaderVersion >= 310; +} + +#if defined(ANGLE_ENABLE_ASSERTS) +bool IsScopeQualifier(TQualifier qualifier) +{ + return qualifier == EvqGlobal || qualifier == EvqTemporary; +} + +bool IsScopeQualifierWrapper(const TQualifierWrapperBase *qualifier) +{ + if (qualifier->getType() != QtStorage) + return false; + const TStorageQualifierWrapper *storageQualifier = + static_cast<const TStorageQualifierWrapper *>(qualifier); + TQualifier q = storageQualifier->getQualifier(); + return IsScopeQualifier(q); +} + +// Returns true if the invariant for the qualifier sequence holds +bool IsInvariantCorrect(const TTypeQualifierBuilder::QualifierSequence &qualifiers) +{ + // We should have at least one qualifier. + // The first qualifier always tells the scope. + return qualifiers.size() >= 1 && IsScopeQualifierWrapper(qualifiers[0]); +} +#endif + +// Returns true if there are qualifiers which have been specified multiple times +// If areQualifierChecksRelaxed is set to true, then layout qualifier repetition is allowed. +bool HasRepeatingQualifiers(const TTypeQualifierBuilder::QualifierSequence &qualifiers, + bool areQualifierChecksRelaxed, + std::string *errorMessage) +{ + bool invariantFound = false; + bool precisionFound = false; + bool layoutFound = false; + bool interpolationFound = false; + + unsigned int locationsSpecified = 0; + bool isOut = false; + + // The iteration starts from one since the first qualifier only reveals the scope of the + // expression. It is inserted first whenever the sequence gets created. + for (size_t i = 1; i < qualifiers.size(); ++i) + { + switch (qualifiers[i]->getType()) + { + case QtInvariant: + { + if (invariantFound) + { + *errorMessage = "The invariant qualifier specified multiple times."; + return true; + } + invariantFound = true; + break; + } + case QtPrecision: + { + if (precisionFound) + { + *errorMessage = "The precision qualifier specified multiple times."; + return true; + } + precisionFound = true; + break; + } + case QtLayout: + { + if (layoutFound && !areQualifierChecksRelaxed) + { + *errorMessage = "The layout qualifier specified multiple times."; + return true; + } + if (invariantFound && !areQualifierChecksRelaxed) + { + // This combination is not correct according to the syntax specified in the + // formal grammar in the ESSL 3.00 spec. In ESSL 3.10 the grammar does not have + // a similar restriction. + *errorMessage = + "The layout qualifier and invariant qualifier cannot coexist in the same " + "declaration according to the grammar."; + return true; + } + layoutFound = true; + const TLayoutQualifier ¤tQualifier = + static_cast<const TLayoutQualifierWrapper *>(qualifiers[i])->getQualifier(); + locationsSpecified += currentQualifier.locationsSpecified; + break; + } + case QtInterpolation: + { + // 'centroid' is treated as a storage qualifier + // 'flat centroid' will be squashed to 'flat' + // 'smooth centroid' will be squashed to 'centroid' + if (interpolationFound) + { + *errorMessage = "The interpolation qualifier specified multiple times."; + return true; + } + interpolationFound = true; + break; + } + case QtStorage: + { + // Go over all of the storage qualifiers up until the current one and check for + // repetitions. + TQualifier currentQualifier = + static_cast<const TStorageQualifierWrapper *>(qualifiers[i])->getQualifier(); + if (currentQualifier == EvqVertexOut || currentQualifier == EvqFragmentOut) + { + isOut = true; + } + for (size_t j = 1; j < i; ++j) + { + if (qualifiers[j]->getType() == QtStorage) + { + const TStorageQualifierWrapper *previousQualifierWrapper = + static_cast<const TStorageQualifierWrapper *>(qualifiers[j]); + TQualifier previousQualifier = previousQualifierWrapper->getQualifier(); + if (currentQualifier == previousQualifier) + { + *errorMessage = previousQualifierWrapper->getQualifierString().c_str(); + *errorMessage += " specified multiple times"; + return true; + } + } + } + break; + } + default: + UNREACHABLE(); + } + } + + if (locationsSpecified > 1 && isOut) + { + // GLSL ES 3.00.6 section 4.3.8.2 Output Layout Qualifiers + // GLSL ES 3.10 section 4.4.2 Output Layout Qualifiers + // "The qualifier may appear at most once within a declaration." + *errorMessage = "Output layout location specified multiple times."; + return true; + } + + return false; +} + +// GLSL ES 3.00_6, 4.7 Order of Qualification +// The correct order of qualifiers is: +// invariant-qualifier interpolation-qualifier storage-qualifier precision-qualifier +// layout-qualifier has to be before storage-qualifier. +bool AreQualifiersInOrder(const TTypeQualifierBuilder::QualifierSequence &qualifiers, + std::string *errorMessage) +{ + bool foundInterpolation = false; + bool foundStorage = false; + bool foundPrecision = false; + for (size_t i = 1; i < qualifiers.size(); ++i) + { + switch (qualifiers[i]->getType()) + { + case QtInvariant: + if (foundInterpolation || foundStorage || foundPrecision) + { + *errorMessage = "The invariant qualifier has to be first in the expression."; + return false; + } + break; + case QtInterpolation: + if (foundStorage) + { + *errorMessage = "Storage qualifiers have to be after interpolation qualifiers."; + return false; + } + else if (foundPrecision) + { + *errorMessage = + "Precision qualifiers have to be after interpolation qualifiers."; + return false; + } + foundInterpolation = true; + break; + case QtLayout: + if (foundStorage) + { + *errorMessage = "Storage qualifiers have to be after layout qualifiers."; + return false; + } + else if (foundPrecision) + { + *errorMessage = "Precision qualifiers have to be after layout qualifiers."; + return false; + } + break; + case QtStorage: + if (foundPrecision) + { + *errorMessage = "Precision qualifiers have to be after storage qualifiers."; + return false; + } + foundStorage = true; + break; + case QtPrecision: + foundPrecision = true; + break; + default: + UNREACHABLE(); + } + } + return true; +} + +struct QualifierComparator +{ + bool operator()(const TQualifierWrapperBase *q1, const TQualifierWrapperBase *q2) + { + return q1->getRank() < q2->getRank(); + } +}; + +void SortSequence(TTypeQualifierBuilder::QualifierSequence &qualifiers) +{ + // We need a stable sorting algorithm since the order of layout-qualifier declarations matter. + // The sorting starts from index 1, instead of 0, since the element at index 0 tells the scope + // and we always want it to be first. + std::stable_sort(qualifiers.begin() + 1, qualifiers.end(), QualifierComparator()); +} + +// Handles the joining of storage qualifiers for variables. +bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier) +{ + switch (*joinedQualifier) + { + case EvqGlobal: + *joinedQualifier = storageQualifier; + break; + case EvqTemporary: + { + switch (storageQualifier) + { + case EvqConst: + *joinedQualifier = storageQualifier; + break; + default: + return false; + } + break; + } + case EvqSmooth: + { + switch (storageQualifier) + { + case EvqCentroid: + *joinedQualifier = EvqCentroid; + break; + case EvqVertexOut: + *joinedQualifier = EvqSmoothOut; + break; + case EvqFragmentIn: + *joinedQualifier = EvqSmoothIn; + break; + default: + return false; + } + break; + } + case EvqFlat: + { + switch (storageQualifier) + { + case EvqCentroid: + *joinedQualifier = EvqFlat; + break; + case EvqVertexOut: + *joinedQualifier = EvqFlatOut; + break; + case EvqFragmentIn: + *joinedQualifier = EvqFlatIn; + break; + default: + return false; + } + break; + } + case EvqCentroid: + { + switch (storageQualifier) + { + case EvqVertexOut: + *joinedQualifier = EvqCentroidOut; + break; + case EvqFragmentIn: + *joinedQualifier = EvqCentroidIn; + break; + default: + return false; + } + break; + } + default: + return false; + } + return true; +} + +// Handles the joining of storage qualifiers for a parameter in a function. +bool JoinParameterStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier) +{ + switch (*joinedQualifier) + { + case EvqTemporary: + *joinedQualifier = storageQualifier; + break; + case EvqConst: + { + switch (storageQualifier) + { + case EvqIn: + *joinedQualifier = EvqConstReadOnly; + break; + default: + return false; + } + break; + } + default: + return false; + } + return true; +} + +TTypeQualifier GetVariableTypeQualifierFromSortedSequence( + const TTypeQualifierBuilder::QualifierSequence &sortedSequence, + TDiagnostics *diagnostics) +{ + TTypeQualifier typeQualifier( + static_cast<const TStorageQualifierWrapper *>(sortedSequence[0])->getQualifier(), + sortedSequence[0]->getLine()); + for (size_t i = 1; i < sortedSequence.size(); ++i) + { + const TQualifierWrapperBase *qualifier = sortedSequence[i]; + bool isQualifierValid = false; + switch (qualifier->getType()) + { + case QtInvariant: + isQualifierValid = true; + typeQualifier.invariant = true; + break; + case QtInterpolation: + { + switch (typeQualifier.qualifier) + { + case EvqGlobal: + isQualifierValid = true; + typeQualifier.qualifier = + static_cast<const TInterpolationQualifierWrapper *>(qualifier) + ->getQualifier(); + break; + default: + isQualifierValid = false; + } + break; + } + case QtLayout: + { + const TLayoutQualifierWrapper *layoutQualifierWrapper = + static_cast<const TLayoutQualifierWrapper *>(qualifier); + isQualifierValid = true; + typeQualifier.layoutQualifier = sh::JoinLayoutQualifiers( + typeQualifier.layoutQualifier, layoutQualifierWrapper->getQualifier(), + layoutQualifierWrapper->getLine(), diagnostics); + break; + } + case QtStorage: + isQualifierValid = JoinVariableStorageQualifier( + &typeQualifier.qualifier, + static_cast<const TStorageQualifierWrapper *>(qualifier)->getQualifier()); + break; + case QtPrecision: + isQualifierValid = true; + typeQualifier.precision = + static_cast<const TPrecisionQualifierWrapper *>(qualifier)->getQualifier(); + ASSERT(typeQualifier.precision != EbpUndefined); + break; + default: + UNREACHABLE(); + } + if (!isQualifierValid) + { + const TString &qualifierString = qualifier->getQualifierString(); + diagnostics->error(qualifier->getLine(), "invalid qualifier combination", + qualifierString.c_str(), ""); + break; + } + } + return typeQualifier; +} + +TTypeQualifier GetParameterTypeQualifierFromSortedSequence( + const TTypeQualifierBuilder::QualifierSequence &sortedSequence, + TDiagnostics *diagnostics) +{ + TTypeQualifier typeQualifier(EvqTemporary, sortedSequence[0]->getLine()); + for (size_t i = 1; i < sortedSequence.size(); ++i) + { + const TQualifierWrapperBase *qualifier = sortedSequence[i]; + bool isQualifierValid = false; + switch (qualifier->getType()) + { + case QtInvariant: + case QtInterpolation: + case QtLayout: + break; + case QtStorage: + isQualifierValid = JoinParameterStorageQualifier( + &typeQualifier.qualifier, + static_cast<const TStorageQualifierWrapper *>(qualifier)->getQualifier()); + break; + case QtPrecision: + isQualifierValid = true; + typeQualifier.precision = + static_cast<const TPrecisionQualifierWrapper *>(qualifier)->getQualifier(); + ASSERT(typeQualifier.precision != EbpUndefined); + break; + default: + UNREACHABLE(); + } + if (!isQualifierValid) + { + const TString &qualifierString = qualifier->getQualifierString(); + diagnostics->error(qualifier->getLine(), "invalid parameter qualifier", + qualifierString.c_str(), ""); + break; + } + } + + switch (typeQualifier.qualifier) + { + case EvqIn: + case EvqConstReadOnly: // const in + case EvqOut: + case EvqInOut: + break; + case EvqConst: + typeQualifier.qualifier = EvqConstReadOnly; + break; + case EvqTemporary: + // no qualifier has been specified, set it to EvqIn which is the default + typeQualifier.qualifier = EvqIn; + break; + default: + diagnostics->error(sortedSequence[0]->getLine(), "Invalid parameter qualifier ", + getQualifierString(typeQualifier.qualifier), ""); + } + return typeQualifier; +} +} // namespace + +unsigned int TInvariantQualifierWrapper::getRank() const +{ + return 0u; +} + +unsigned int TInterpolationQualifierWrapper::getRank() const +{ + return 1u; +} + +unsigned int TLayoutQualifierWrapper::getRank() const +{ + return 2u; +} + +unsigned int TStorageQualifierWrapper::getRank() const +{ + // Force the 'centroid' auxilary storage qualifier to be always first among all storage + // qualifiers. + if (mStorageQualifier == EvqCentroid) + { + return 3u; + } + else + { + return 4u; + } +} + +unsigned int TPrecisionQualifierWrapper::getRank() const +{ + return 5u; +} + +TTypeQualifier::TTypeQualifier(TQualifier scope, const TSourceLoc &loc) + : layoutQualifier(TLayoutQualifier::create()), + precision(EbpUndefined), + qualifier(scope), + invariant(false), + line(loc) +{ + ASSERT(IsScopeQualifier(qualifier)); +} + +TTypeQualifierBuilder::TTypeQualifierBuilder(const TStorageQualifierWrapper *scope, + int shaderVersion) + : mShaderVersion(shaderVersion) +{ + ASSERT(IsScopeQualifier(scope->getQualifier())); + mQualifiers.push_back(scope); +} + +void TTypeQualifierBuilder::appendQualifier(const TQualifierWrapperBase *qualifier) +{ + mQualifiers.push_back(qualifier); +} + +bool TTypeQualifierBuilder::checkSequenceIsValid(TDiagnostics *diagnostics) const +{ + bool areQualifierChecksRelaxed = AreTypeQualifierChecksRelaxed(mShaderVersion); + std::string errorMessage; + if (HasRepeatingQualifiers(mQualifiers, areQualifierChecksRelaxed, &errorMessage)) + { + diagnostics->error(mQualifiers[0]->getLine(), "qualifier sequence", errorMessage.c_str(), + ""); + return false; + } + + if (!areQualifierChecksRelaxed && !AreQualifiersInOrder(mQualifiers, &errorMessage)) + { + diagnostics->error(mQualifiers[0]->getLine(), "qualifier sequence", errorMessage.c_str(), + ""); + return false; + } + + return true; +} + +TTypeQualifier TTypeQualifierBuilder::getParameterTypeQualifier(TDiagnostics *diagnostics) const +{ + ASSERT(IsInvariantCorrect(mQualifiers)); + ASSERT(static_cast<const TStorageQualifierWrapper *>(mQualifiers[0])->getQualifier() == + EvqTemporary); + + if (!checkSequenceIsValid(diagnostics)) + { + return TTypeQualifier(EvqTemporary, mQualifiers[0]->getLine()); + } + + // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so + // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to + // combine the qualifiers. + if (AreTypeQualifierChecksRelaxed(mShaderVersion)) + { + // Copy the qualifier sequence so that we can sort them. + QualifierSequence sortedQualifierSequence = mQualifiers; + SortSequence(sortedQualifierSequence); + return GetParameterTypeQualifierFromSortedSequence(sortedQualifierSequence, diagnostics); + } + return GetParameterTypeQualifierFromSortedSequence(mQualifiers, diagnostics); +} + +TTypeQualifier TTypeQualifierBuilder::getVariableTypeQualifier(TDiagnostics *diagnostics) const +{ + ASSERT(IsInvariantCorrect(mQualifiers)); + + if (!checkSequenceIsValid(diagnostics)) + { + return TTypeQualifier( + static_cast<const TStorageQualifierWrapper *>(mQualifiers[0])->getQualifier(), + mQualifiers[0]->getLine()); + } + + // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so + // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to + // combine the qualifiers. + if (AreTypeQualifierChecksRelaxed(mShaderVersion)) + { + // Copy the qualifier sequence so that we can sort them. + QualifierSequence sortedQualifierSequence = mQualifiers; + SortSequence(sortedQualifierSequence); + return GetVariableTypeQualifierFromSortedSequence(sortedQualifierSequence, diagnostics); + } + return GetVariableTypeQualifierFromSortedSequence(mQualifiers, diagnostics); +} diff --git a/chromium/third_party/angle/src/compiler/translator/QualifierTypes.h b/chromium/third_party/angle/src/compiler/translator/QualifierTypes.h new file mode 100644 index 00000000000..0bcc39a16e4 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/QualifierTypes.h @@ -0,0 +1,170 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_ +#define COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_ + +#include "common/angleutils.h" +#include "compiler/translator/BaseTypes.h" +#include "compiler/translator/Types.h" + +class TDiagnostics; + +namespace sh +{ +TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation, + TDiagnostics *diagnostics); +} // namespace sh + +enum TQualifierType +{ + QtInvariant, + QtInterpolation, + QtLayout, + QtStorage, + QtPrecision +}; + +class TQualifierWrapperBase : angle::NonCopyable +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TQualifierWrapperBase(const TSourceLoc &line) : mLine(line) {} + virtual ~TQualifierWrapperBase(){}; + virtual TQualifierType getType() const = 0; + virtual TString getQualifierString() const = 0; + virtual unsigned int getRank() const = 0; + const TSourceLoc &getLine() const { return mLine; } + private: + TSourceLoc mLine; +}; + +class TInvariantQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TInvariantQualifierWrapper(const TSourceLoc &line) : TQualifierWrapperBase(line) {} + ~TInvariantQualifierWrapper() {} + + TQualifierType getType() const { return QtInvariant; } + TString getQualifierString() const { return "invariant"; } + unsigned int getRank() const; +}; + +class TInterpolationQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TInterpolationQualifierWrapper(TQualifier interpolationQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mInterpolationQualifier(interpolationQualifier) + { + } + ~TInterpolationQualifierWrapper() {} + + TQualifierType getType() const { return QtInterpolation; } + TString getQualifierString() const { return ::getQualifierString(mInterpolationQualifier); } + TQualifier getQualifier() const { return mInterpolationQualifier; } + unsigned int getRank() const; + + private: + TQualifier mInterpolationQualifier; +}; + +class TLayoutQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TLayoutQualifierWrapper(TLayoutQualifier layoutQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mLayoutQualifier(layoutQualifier) + { + } + ~TLayoutQualifierWrapper() {} + + TQualifierType getType() const { return QtLayout; } + TString getQualifierString() const { return "layout"; } + const TLayoutQualifier &getQualifier() const { return mLayoutQualifier; } + unsigned int getRank() const; + + private: + TLayoutQualifier mLayoutQualifier; +}; + +class TStorageQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TStorageQualifierWrapper(TQualifier storageQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mStorageQualifier(storageQualifier) + { + } + ~TStorageQualifierWrapper() {} + + TQualifierType getType() const { return QtStorage; } + TString getQualifierString() const { return ::getQualifierString(mStorageQualifier); } + TQualifier getQualifier() const { return mStorageQualifier; } + unsigned int getRank() const; + + private: + TQualifier mStorageQualifier; +}; + +class TPrecisionQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TPrecisionQualifierWrapper(TPrecision precisionQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mPrecisionQualifier(precisionQualifier) + { + } + ~TPrecisionQualifierWrapper() {} + + TQualifierType getType() const { return QtPrecision; } + TString getQualifierString() const { return ::getPrecisionString(mPrecisionQualifier); } + TPrecision getQualifier() const { return mPrecisionQualifier; } + unsigned int getRank() const; + + private: + TPrecision mPrecisionQualifier; +}; + +// TTypeQualifier tightly covers type_qualifier from the grammar +struct TTypeQualifier +{ + // initializes all of the qualifiers and sets the scope + TTypeQualifier(TQualifier scope, const TSourceLoc &loc); + + TLayoutQualifier layoutQualifier; + TPrecision precision; + TQualifier qualifier; + bool invariant; + TSourceLoc line; +}; + +// TTypeQualifierBuilder contains all of the qualifiers when type_qualifier gets parsed. +// It is to be used to validate the qualifier sequence and build a TTypeQualifier from it. +class TTypeQualifierBuilder : angle::NonCopyable +{ + public: + using QualifierSequence = TVector<const TQualifierWrapperBase *>; + + public: + POOL_ALLOCATOR_NEW_DELETE(); + TTypeQualifierBuilder(const TStorageQualifierWrapper *scope, int shaderVersion); + // Adds the passed qualifier to the end of the sequence. + void appendQualifier(const TQualifierWrapperBase *qualifier); + // Checks for the order of qualification and repeating qualifiers. + bool checkSequenceIsValid(TDiagnostics *diagnostics) const; + // Goes over the qualifier sequence and parses it to form a type qualifier for a function + // parameter. + // The returned object is initialized even if the parsing fails. + TTypeQualifier getParameterTypeQualifier(TDiagnostics *diagnostics) const; + // Goes over the qualifier sequence and parses it to form a type qualifier for a variable. + // The returned object is initialized even if the parsing fails. + TTypeQualifier getVariableTypeQualifier(TDiagnostics *diagnostics) const; + + private: + QualifierSequence mQualifiers; + int mShaderVersion; +}; + +#endif // COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/RecordConstantPrecision.cpp b/chromium/third_party/angle/src/compiler/translator/RecordConstantPrecision.cpp index 14e88b749a7..af1d1d1a38c 100644 --- a/chromium/third_party/angle/src/compiler/translator/RecordConstantPrecision.cpp +++ b/chromium/third_party/angle/src/compiler/translator/RecordConstantPrecision.cpp @@ -128,7 +128,7 @@ void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion * TIntermSequence insertions; insertions.push_back(createTempInitDeclaration(node, EvqConst)); insertStatementsInParentBlock(insertions); - mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, createTempSymbol(node->getType()), false)); + queueReplacement(node, createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); mFoundHigherPrecisionConstant = true; } diff --git a/chromium/third_party/angle/src/compiler/translator/RemoveDynamicIndexing.cpp b/chromium/third_party/angle/src/compiler/translator/RemoveDynamicIndexing.cpp index 74814f22a79..4ac3e9fcd12 100644 --- a/chromium/third_party/angle/src/compiler/translator/RemoveDynamicIndexing.cpp +++ b/chromium/third_party/angle/src/compiler/translator/RemoveDynamicIndexing.cpp @@ -11,6 +11,7 @@ #include "compiler/translator/InfoSink.h" #include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" #include "compiler/translator/SymbolTable.h" namespace @@ -91,21 +92,15 @@ TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType, const int index, TQualifier baseQualifier) { - TIntermBinary *indexNode = new TIntermBinary(EOpIndexDirect); - indexNode->setType(fieldType); TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier); - indexNode->setLeft(baseSymbol); - indexNode->setRight(CreateIntConstantNode(index)); + TIntermBinary *indexNode = + new TIntermBinary(EOpIndexDirect, baseSymbol, TIntermTyped::CreateIndexNode(index)); return indexNode; } TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType) { - TIntermBinary *assignNode = new TIntermBinary(EOpAssign); - assignNode->setType(assignedValueType); - assignNode->setLeft(targetNode); - assignNode->setRight(CreateValueSymbol(assignedValueType)); - return assignNode; + return new TIntermBinary(EOpAssign, targetNode, CreateValueSymbol(assignedValueType)); } TIntermTyped *EnsureSignedInt(TIntermTyped *node) @@ -255,10 +250,9 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence); bodyNode->getSequence()->push_back(switchNode); - TIntermBinary *cond = new TIntermBinary(EOpLessThan); + TIntermBinary *cond = + new TIntermBinary(EOpLessThan, CreateIndexSymbol(), CreateIntConstantNode(0)); cond->setType(TType(EbtBool, EbpUndefined)); - cond->setLeft(CreateIndexSymbol()); - cond->setRight(CreateIntConstantNode(0)); // Two blocks: one accesses (either reads or writes) the first element and returns, // the other accesses the last element. @@ -286,7 +280,7 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode); useLastBlock->getSequence()->push_back(returnLastNode); } - TIntermSelection *ifNode = new TIntermSelection(cond, useFirstBlock, nullptr); + TIntermIfElse *ifNode = new TIntermIfElse(cond, useFirstBlock, nullptr); bodyNode->getSequence()->push_back(ifNode); bodyNode->getSequence()->push_back(useLastBlock); @@ -398,20 +392,25 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod // Init the temp variable holding the index TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight()); - TIntermSequence insertions; - insertions.push_back(initIndex); - insertStatementsInParentBlock(insertions); + insertStatementInParentBlock(initIndex); mUsedTreeInsertion = true; // Replace the index with the temp variable TIntermSymbol *tempIndex = createTempSymbol(node->getRight()->getType()); - NodeUpdateEntry replaceIndex(node, node->getRight(), tempIndex, false); - mReplacements.push_back(replaceIndex); + queueReplacementWithParent(node, node->getRight(), tempIndex, OriginalNode::IS_DROPPED); } - else if (!node->getLeft()->isArray() && node->getLeft()->getBasicType() != EbtStruct) + else if (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node)) { bool write = isLValueRequiredHere(); +#if defined(ANGLE_ENABLE_ASSERTS) + // Make sure that IntermNodePatternMatcher is consistent with the slightly differently + // implemented checks in this traverser. + IntermNodePatternMatcher matcher( + IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue); + ASSERT(matcher.match(node, getParentNode(), isLValueRequiredHere()) == write); +#endif + TType type = node->getLeft()->getType(); mIndexedVecAndMatrixTypes.insert(type); @@ -462,9 +461,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod CreateIndexedWriteFunctionCall(node, tempIndex, createTempSymbol(fieldType)); insertionsAfter.push_back(indexedWriteCall); insertStatementsInParentBlock(insertionsBefore, insertionsAfter); - NodeUpdateEntry replaceIndex(getParentNode(), node, createTempSymbol(fieldType), - false); - mReplacements.push_back(replaceIndex); + queueReplacement(node, createTempSymbol(fieldType), OriginalNode::IS_DROPPED); mUsedTreeInsertion = true; } else @@ -477,8 +474,7 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod ASSERT(!mRemoveIndexSideEffectsInSubtree); TIntermAggregate *indexingCall = CreateIndexFunctionCall( node, node->getLeft(), EnsureSignedInt(node->getRight())); - NodeUpdateEntry replaceIndex(getParentNode(), node, indexingCall, false); - mReplacements.push_back(replaceIndex); + queueReplacement(node, indexingCall, OriginalNode::IS_DROPPED); } } } diff --git a/chromium/third_party/angle/src/compiler/translator/RemovePow.cpp b/chromium/third_party/angle/src/compiler/translator/RemovePow.cpp index 6dbb48da9cd..4b0fe694886 100644 --- a/chromium/third_party/angle/src/compiler/translator/RemovePow.cpp +++ b/chromium/third_party/angle/src/compiler/translator/RemovePow.cpp @@ -52,31 +52,20 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node) { if (IsProblematicPow(node)) { - TInfoSink nullSink; - TIntermTyped *x = node->getSequence()->at(0)->getAsTyped(); TIntermTyped *y = node->getSequence()->at(1)->getAsTyped(); - TIntermUnary *log = new TIntermUnary(EOpLog2); - log->setOperand(x); + TIntermUnary *log = new TIntermUnary(EOpLog2, x); log->setLine(node->getLine()); - log->setType(x->getType()); - TIntermBinary *mul = new TIntermBinary(EOpMul); - mul->setLeft(y); - mul->setRight(log); + TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType()); + TIntermBinary *mul = new TIntermBinary(op, y, log); mul->setLine(node->getLine()); - bool valid = mul->promote(nullSink); - UNUSED_ASSERTION_VARIABLE(valid); - ASSERT(valid); - TIntermUnary *exp = new TIntermUnary(EOpExp2); - exp->setOperand(mul); + TIntermUnary *exp = new TIntermUnary(EOpExp2, mul); exp->setLine(node->getLine()); - exp->setType(node->getType()); - NodeUpdateEntry replacePow(getParentNode(), node, exp, false); - mReplacements.push_back(replacePow); + queueReplacement(node, exp, OriginalNode::IS_DROPPED); // If the x parameter also needs to be replaced, we need to do that in another traversal, // since it's parent node will change in a way that's not handled correctly by updateTree(). diff --git a/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp b/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp index b278b53436e..521cbeb6dbe 100644 --- a/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp +++ b/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp @@ -62,7 +62,14 @@ bool RemoveSwitchFallThrough::visitUnary(Visit, TIntermUnary *node) return false; } -bool RemoveSwitchFallThrough::visitSelection(Visit, TIntermSelection *node) +bool RemoveSwitchFallThrough::visitTernary(Visit, TIntermTernary *node) +{ + mPreviousCase->getSequence()->push_back(node); + mLastStatementWasBreak = false; + return false; +} + +bool RemoveSwitchFallThrough::visitIfElse(Visit, TIntermIfElse *node) { mPreviousCase->getSequence()->push_back(node); mLastStatementWasBreak = false; diff --git a/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.h b/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.h index db8699327c1..fc73da7a3c3 100644 --- a/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.h +++ b/chromium/third_party/angle/src/compiler/translator/RemoveSwitchFallThrough.h @@ -23,7 +23,8 @@ class RemoveSwitchFallThrough : public TIntermTraverser void visitConstantUnion(TIntermConstantUnion *node) override; bool visitBinary(Visit, TIntermBinary *node) override; bool visitUnary(Visit, TIntermUnary *node) override; - bool visitSelection(Visit visit, TIntermSelection *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + bool visitIfElse(Visit visit, TIntermIfElse *node) override; bool visitSwitch(Visit, TIntermSwitch *node) override; bool visitCase(Visit, TIntermCase *node) override; bool visitAggregate(Visit, TIntermAggregate *node) override; diff --git a/chromium/third_party/angle/src/compiler/translator/RenameFunction.h b/chromium/third_party/angle/src/compiler/translator/RenameFunction.h deleted file mode 100644 index fd6a365fea8..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/RenameFunction.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_RENAMEFUNCTION_H_ -#define COMPILER_TRANSLATOR_RENAMEFUNCTION_H_ - -#include "compiler/translator/IntermNode.h" - -// -// Renames a function, including its declaration and any calls to it. -// -class RenameFunction : public TIntermTraverser -{ -public: - RenameFunction(const TString& oldFunctionName, const TString& newFunctionName) - : TIntermTraverser(true, false, false) - , mOldFunctionName(oldFunctionName) - , mNewFunctionName(newFunctionName) {} - - bool visitAggregate(Visit visit, TIntermAggregate *node) override - { - TOperator op = node->getOp(); - if ((op == EOpFunction || op == EOpFunctionCall) && node->getName() == mOldFunctionName) - node->setName(mNewFunctionName); - return true; - } - -private: - const TString mOldFunctionName; - const TString mNewFunctionName; -}; - -#endif // COMPILER_TRANSLATOR_RENAMEFUNCTION_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteDoWhile.cpp b/chromium/third_party/angle/src/compiler/translator/RewriteDoWhile.cpp index 83474475461..3a62de2d3a1 100644 --- a/chromium/third_party/angle/src/compiler/translator/RewriteDoWhile.cpp +++ b/chromium/third_party/angle/src/compiler/translator/RewriteDoWhile.cpp @@ -95,23 +95,22 @@ class DoWhileRewriter : public TIntermTraverser // break; // } // } - TIntermSelection *breakIf = nullptr; + TIntermIfElse *breakIf = nullptr; { TIntermBranch *breakStatement = new TIntermBranch(EOpBreak, nullptr); TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence); breakBlock->getSequence()->push_back(breakStatement); - TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot); - negatedCondition->setOperand(loop->getCondition()); + TIntermUnary *negatedCondition = + new TIntermUnary(EOpLogicalNot, loop->getCondition()); - TIntermSelection *innerIf = - new TIntermSelection(negatedCondition, breakBlock, nullptr); + TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr); TIntermAggregate *innerIfBlock = new TIntermAggregate(EOpSequence); innerIfBlock->getSequence()->push_back(innerIf); - breakIf = new TIntermSelection(createTempSymbol(boolType), innerIfBlock, nullptr); + breakIf = new TIntermIfElse(createTempSymbol(boolType), innerIfBlock, nullptr); } // Assemble the replacement loops, reusing the do-while loop's body and inserting our diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp b/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp index 52ede17434a..13d71c799f1 100644 --- a/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp +++ b/chromium/third_party/angle/src/compiler/translator/RewriteElseBlocks.cpp @@ -8,6 +8,8 @@ // #include "compiler/translator/RewriteElseBlocks.h" + +#include "compiler/translator/Intermediate.h" #include "compiler/translator/NodeSearch.h" #include "compiler/translator/SymbolTable.h" @@ -28,16 +30,9 @@ class ElseBlockRewriter : public TIntermTraverser private: const TType *mFunctionType; - TIntermNode *rewriteSelection(TIntermSelection *selection); + TIntermNode *rewriteIfElse(TIntermIfElse *ifElse); }; -TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand) -{ - TIntermUnary *unary = new TIntermUnary(op, operand->getType()); - unary->setOperand(operand); - return unary; -} - ElseBlockRewriter::ElseBlockRewriter() : TIntermTraverser(true, false, true), mFunctionType(NULL) @@ -53,19 +48,10 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) for (size_t statementIndex = 0; statementIndex != node->getSequence()->size(); statementIndex++) { TIntermNode *statement = (*node->getSequence())[statementIndex]; - TIntermSelection *selection = statement->getAsSelectionNode(); - if (selection && selection->getFalseBlock() != nullptr) + TIntermIfElse *ifElse = statement->getAsIfElseNode(); + if (ifElse && ifElse->getFalseBlock() != nullptr) { - // Check for if / else if - TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode(); - if (elseIfBranch) - { - selection->replaceChildNode(elseIfBranch, rewriteSelection(elseIfBranch)); - delete elseIfBranch; - } - - (*node->getSequence())[statementIndex] = rewriteSelection(selection); - delete selection; + (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse); } } } @@ -82,20 +68,20 @@ bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) return true; } -TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) +TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse) { - ASSERT(selection != nullptr); + ASSERT(ifElse != nullptr); nextTemporaryIndex(); - TIntermTyped *typedCondition = selection->getCondition()->getAsTyped(); + TIntermTyped *typedCondition = ifElse->getCondition()->getAsTyped(); TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition); - TIntermSelection *falseBlock = nullptr; + TIntermAggregate *falseBlock = nullptr; TType boolType(EbtBool, EbpUndefined, EvqTemporary); - if (selection->getFalseBlock()) + if (ifElse->getFalseBlock()) { TIntermAggregate *negatedElse = nullptr; // crbug.com/346463 @@ -113,17 +99,19 @@ TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) } TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType); - TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse); - falseBlock = new TIntermSelection(negatedCondition, - selection->getFalseBlock(), negatedElse); + TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot, conditionSymbolElse); + TIntermIfElse *falseIfElse = + new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse); + falseBlock = TIntermediate::EnsureSequence(falseIfElse); } TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType); - TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, selection->getTrueBlock(), falseBlock); + TIntermIfElse *newIfElse = + new TIntermIfElse(conditionSymbolSel, ifElse->getTrueBlock(), falseBlock); TIntermAggregate *block = new TIntermAggregate(EOpSequence); block->getSequence()->push_back(storeCondition); - block->getSequence()->push_back(newSelection); + block->getSequence()->push_back(newIfElse); return block; } diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp b/chromium/third_party/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp new file mode 100644 index 00000000000..bcd0bb5b21b --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp @@ -0,0 +1,171 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of texelFetchOffset translation issue workaround. +// See header for more info. + +#include "compiler/translator/RewriteTexelFetchOffset.h" + +#include "common/angleutils.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +class Traverser : public TIntermTraverser +{ + public: + static void Apply(TIntermNode *root, + const TSymbolTable &symbolTable, + int shaderVersion); + + private: + Traverser(const TSymbolTable &symbolTable, int shaderVersion); + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + void nextIteration(); + + const TSymbolTable *symbolTable; + const int shaderVersion; + bool mFound = false; +}; + +Traverser::Traverser(const TSymbolTable &symbolTable, int shaderVersion) + : TIntermTraverser(true, false, false), symbolTable(&symbolTable), shaderVersion(shaderVersion) +{ +} + +// static +void Traverser::Apply(TIntermNode *root, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + Traverser traverser(symbolTable, shaderVersion); + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.mFound) + { + traverser.updateTree(); + } + } while (traverser.mFound); +} + +void Traverser::nextIteration() +{ + mFound = false; +} + +bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mFound) + { + return false; + } + + // Decide if the node represents the call of texelFetchOffset. + if (node->getOp() != EOpFunctionCall || node->isUserDefined()) + { + return true; + } + + if (node->getName().compare(0, 16, "texelFetchOffset") != 0) + { + return true; + } + + // Potential problem case detected, apply workaround. + const TIntermSequence *sequence = node->getSequence(); + ASSERT(sequence->size() == 4u); + + // Decide if there is a 2DArray sampler. + bool is2DArray = node->getName().find("s2a1") != TString::npos; + + // Create new argument list from node->getName(). + // e.g. Get "(is2a1;vi3;i1;" from "texelFetchOffset(is2a1;vi3;i1;vi2;" + TString newArgs = node->getName().substr(16, node->getName().length() - 20); + TString newName = "texelFetch" + newArgs; + TSymbol *texelFetchSymbol = symbolTable->findBuiltIn(newName, shaderVersion); + ASSERT(texelFetchSymbol); + int uniqueId = texelFetchSymbol->getUniqueId(); + + // Create new node that represents the call of function texelFetch. + TIntermAggregate *texelFetchNode = new TIntermAggregate(EOpFunctionCall); + texelFetchNode->setName(newName); + texelFetchNode->setFunctionId(uniqueId); + texelFetchNode->setType(node->getType()); + texelFetchNode->setLine(node->getLine()); + + // Create argument List of texelFetch(sampler, Position+offset, lod). + TIntermSequence newsequence; + + // sampler + newsequence.push_back(sequence->at(0)); + + // Position + TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped(); + ASSERT(texCoordNode); + // offset + TIntermTyped *offsetNode = nullptr; + ASSERT(sequence->at(3)->getAsTyped()); + if (is2DArray) + { + // For 2DArray samplers, Position is ivec3 and offset is ivec2; + // So offset must be converted into an ivec3 before being added to Position. + TIntermAggregate *constructIVec3Node = new TIntermAggregate(EOpConstructIVec3); + constructIVec3Node->setLine(texCoordNode->getLine()); + constructIVec3Node->setType(texCoordNode->getType()); + + TIntermSequence ivec3Sequence; + ivec3Sequence.push_back(sequence->at(3)->getAsTyped()); + + TConstantUnion *zero = new TConstantUnion(); + zero->setIConst(0); + TType *intType = new TType(EbtInt); + + TIntermConstantUnion *zeroNode = new TIntermConstantUnion(zero, *intType); + ivec3Sequence.push_back(zeroNode); + constructIVec3Node->insertChildNodes(0, ivec3Sequence); + + offsetNode = constructIVec3Node; + } + else + { + offsetNode = sequence->at(3)->getAsTyped(); + } + + // Position+offset + TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode); + add->setLine(texCoordNode->getLine()); + newsequence.push_back(add); + + // lod + newsequence.push_back(sequence->at(2)); + texelFetchNode->insertChildNodes(0, newsequence); + + // Replace the old node by this new node. + queueReplacement(node, texelFetchNode, OriginalNode::IS_DROPPED); + mFound = true; + return false; +} + +} // anonymous namespace + +void RewriteTexelFetchOffset(TIntermNode *root, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + // texelFetchOffset is only valid in GLSL 3.0 and later. + if (shaderVersion < 300) + return; + + Traverser::Apply(root, symbolTable, shaderVersion); +} + +} // namespace sh
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteTexelFetchOffset.h b/chromium/third_party/angle/src/compiler/translator/RewriteTexelFetchOffset.h new file mode 100644 index 00000000000..4218f0b69a1 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/RewriteTexelFetchOffset.h @@ -0,0 +1,30 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This mutating tree traversal works around an issue on the translation +// from texelFetchOffset into HLSL function Load on INTEL drivers. It +// works by translating texelFetchOffset into texelFetch: +// +// - From: texelFetchOffset(sampler, Position, lod, offset) +// - To: texelFetch(sampler, Position+offset, lod) +// +// See http://anglebug.com/1469 + +#ifndef COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_ +#define COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_ + +class TIntermNode; +class TSymbolTable; + +namespace sh +{ + +void RewriteTexelFetchOffset(TIntermNode *root, + const TSymbolTable &symbolTable, + int shaderVersion); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp b/chromium/third_party/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp new file mode 100644 index 00000000000..ef708cb2e2e --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp @@ -0,0 +1,112 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of evaluating unary integer variable bug workaround. +// See header for more info. + +#include "compiler/translator/RewriteUnaryMinusOperatorInt.h" + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +namespace +{ + +class Traverser : public TIntermTraverser +{ + public: + static void Apply(TIntermNode *root); + + private: + Traverser(); + bool visitUnary(Visit visit, TIntermUnary *node) override; + void nextIteration(); + + bool mFound = false; +}; + +// static +void Traverser::Apply(TIntermNode *root) +{ + Traverser traverser; + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.mFound) + { + traverser.updateTree(); + } + } while (traverser.mFound); +} + +Traverser::Traverser() : TIntermTraverser(true, false, false) +{ +} + +void Traverser::nextIteration() +{ + mFound = false; +} + +bool Traverser::visitUnary(Visit visit, TIntermUnary *node) +{ + if (mFound) + { + return false; + } + + // Decide if the current unary operator is unary minus. + if (node->getOp() != EOpNegative) + { + return true; + } + + // Decide if the current operand is an integer variable. + TIntermTyped *opr = node->getOperand(); + if (!opr->getType().isScalarInt()) + { + return true; + } + + // Potential problem case detected, apply workaround: -(int) -> ~(int) + 1. + // ~(int) + TIntermUnary *bitwiseNot = new TIntermUnary(EOpBitwiseNot, opr); + bitwiseNot->setLine(opr->getLine()); + + // Constant 1 (or 1u) + TConstantUnion *one = new TConstantUnion(); + if (opr->getType().getBasicType() == EbtInt) + { + one->setIConst(1); + } + else + { + one->setUConst(1u); + } + TIntermConstantUnion *oneNode = new TIntermConstantUnion(one, opr->getType()); + oneNode->getTypePointer()->setQualifier(EvqConst); + oneNode->setLine(opr->getLine()); + + // ~(int) + 1 + TIntermBinary *add = new TIntermBinary(EOpAdd, bitwiseNot, oneNode); + add->setLine(opr->getLine()); + + queueReplacement(node, add, OriginalNode::IS_DROPPED); + + mFound = true; + return false; +} + +} // anonymous namespace + +void RewriteUnaryMinusOperatorInt(TIntermNode *root) +{ + Traverser::Apply(root); +} + +} // namespace sh
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h b/chromium/third_party/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h new file mode 100644 index 00000000000..50f0c442a73 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h @@ -0,0 +1,20 @@ +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This mutating tree traversal works around a bug on evaluating unary +// integer variable on Intel D3D driver. It works by rewriting -(int) to +// ~(int) + 1 when evaluating unary integer variables. + +#ifndef COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_ +#define COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_ + +class TIntermNode; +namespace sh +{ + +void RewriteUnaryMinusOperatorInt(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_
\ No newline at end of file diff --git a/chromium/third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/chromium/third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp index 775c5d87101..cb690595924 100644 --- a/chromium/third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp @@ -37,23 +37,9 @@ bool ContainsVectorNode(const TIntermSequence &sequence) return false; } -TIntermConstantUnion *ConstructIndexNode(int index) -{ - TConstantUnion *u = new TConstantUnion[1]; - u[0].setIConst(index); - - TType type(EbtInt, EbpUndefined, EvqConst, 1); - TIntermConstantUnion *node = new TIntermConstantUnion(u, type); - return node; -} - TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index) { - TIntermBinary *binary = new TIntermBinary(EOpIndexDirect); - binary->setLeft(symbolNode); - TIntermConstantUnion *indexNode = ConstructIndexNode(index); - binary->setRight(indexNode); - return binary; + return new TIntermBinary(EOpIndexDirect, symbolNode, TIntermTyped::CreateIndexNode(index)); } TIntermBinary *ConstructMatrixIndexBinaryNode( @@ -62,11 +48,8 @@ TIntermBinary *ConstructMatrixIndexBinaryNode( TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex); - TIntermBinary *binary = new TIntermBinary(EOpIndexDirect); - binary->setLeft(colVectorNode); - TIntermConstantUnion *rowIndexNode = ConstructIndexNode(rowIndex); - binary->setRight(rowIndexNode); - return binary; + return new TIntermBinary(EOpIndexDirect, colVectorNode, + TIntermTyped::CreateIndexNode(rowIndex)); } } // namespace anonymous @@ -278,11 +261,8 @@ TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *orig type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium); } - TIntermBinary *init = new TIntermBinary(EOpInitialize); TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type); - init->setLeft(symbolNode); - init->setRight(original); - init->setType(type); + TIntermBinary *init = new TIntermBinary(EOpInitialize, symbolNode, original); TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration); decl->getSequence()->push_back(init); diff --git a/chromium/third_party/angle/src/compiler/translator/SeparateArrayInitialization.cpp b/chromium/third_party/angle/src/compiler/translator/SeparateArrayInitialization.cpp index de9050cd80a..e166eac4aa4 100644 --- a/chromium/third_party/angle/src/compiler/translator/SeparateArrayInitialization.cpp +++ b/chromium/third_party/angle/src/compiler/translator/SeparateArrayInitialization.cpp @@ -69,10 +69,8 @@ bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node) replacementDeclaration->setLine(symbol->getLine()); replacements.push_back(replacementDeclaration); - TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign); - replacementAssignment->setLeft(symbol); - replacementAssignment->setRight(initializer); - replacementAssignment->setType(initializer->getType()); + TIntermBinary *replacementAssignment = + new TIntermBinary(EOpAssign, symbol, initializer); replacementAssignment->setLine(symbol->getLine()); replacements.push_back(replacementAssignment); diff --git a/chromium/third_party/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp b/chromium/third_party/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp index e8e1a21d9c4..20e47974c6d 100644 --- a/chromium/third_party/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp +++ b/chromium/third_party/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp @@ -12,6 +12,7 @@ #include "compiler/translator/SeparateExpressionsReturningArrays.h" #include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" namespace { @@ -32,11 +33,14 @@ class SeparateExpressionsTraverser : public TIntermTraverser // Marked to true once an operation that needs to be hoisted out of the expression has been found. // After that, no more AST updates are performed on that traversal. bool mFoundArrayExpression; + + IntermNodePatternMatcher mPatternToSeparateMatcher; }; SeparateExpressionsTraverser::SeparateExpressionsTraverser() : TIntermTraverser(true, false, false), - mFoundArrayExpression(false) + mFoundArrayExpression(false), + mPatternToSeparateMatcher(IntermNodePatternMatcher::kExpressionReturningArray) { } @@ -45,11 +49,7 @@ SeparateExpressionsTraverser::SeparateExpressionsTraverser() // and also needs to be replaced in its original location by a different node. TIntermBinary *CopyAssignmentNode(TIntermBinary *node) { - TIntermBinary *copyNode = new TIntermBinary(node->getOp()); - copyNode->setLeft(node->getLeft()); - copyNode->setRight(node->getRight()); - copyNode->setType(node->getType()); - return copyNode; + return new TIntermBinary(node->getOp(), node->getLeft(), node->getRight()); } // Performs a shallow copy of a constructor/function call node. @@ -73,31 +73,25 @@ bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node) if (mFoundArrayExpression) return false; - // Early return if the expression is not an array or if we're not inside a complex expression. - if (!node->getType().isArray() || parentNodeIsBlock()) + // Return if the expression is not an array or if we're not inside a complex expression. + if (!mPatternToSeparateMatcher.match(node, getParentNode())) return true; - switch (node->getOp()) - { - case EOpAssign: - { - mFoundArrayExpression = true; - - TIntermSequence insertions; - insertions.push_back(CopyAssignmentNode(node)); - // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just use the - // original target of the assignment. Care must be taken so that this doesn't happen when the same array - // symbol is a target of assignment more than once in one expression. - insertions.push_back(createTempInitDeclaration(node->getLeft())); - insertStatementsInParentBlock(insertions); - - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); - } - return false; - default: - return true; - } + ASSERT(node->getOp() == EOpAssign); + + mFoundArrayExpression = true; + + TIntermSequence insertions; + insertions.push_back(CopyAssignmentNode(node)); + // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just + // use the original target of the assignment. Care must be taken so that this doesn't happen + // when the same array symbol is a target of assignment more than once in one expression. + insertions.push_back(createTempInitDeclaration(node->getLeft())); + insertStatementsInParentBlock(insertions); + + queueReplacement(node, createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); + + return false; } bool SeparateExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) @@ -105,43 +99,20 @@ bool SeparateExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate if (mFoundArrayExpression) return false; // No need to traverse further - if (getParentNode() != nullptr) - { - TIntermBinary *parentBinary = getParentNode()->getAsBinaryNode(); - bool parentIsAssignment = (parentBinary != nullptr && - (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize)); - - if (!node->getType().isArray() || parentNodeIsBlock() || parentIsAssignment) - return true; - - if (node->isConstructor()) - { - mFoundArrayExpression = true; - - TIntermSequence insertions; - insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); - insertStatementsInParentBlock(insertions); + if (!mPatternToSeparateMatcher.match(node, getParentNode())) + return true; - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); + ASSERT(node->isConstructor() || node->getOp() == EOpFunctionCall); - return false; - } - else if (node->getOp() == EOpFunctionCall) - { - mFoundArrayExpression = true; + mFoundArrayExpression = true; - TIntermSequence insertions; - insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); - insertStatementsInParentBlock(insertions); + TIntermSequence insertions; + insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); + insertStatementsInParentBlock(insertions); - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); + queueReplacement(node, createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); - return false; - } - } - return true; + return false; } void SeparateExpressionsTraverser::nextIteration() diff --git a/chromium/third_party/angle/src/compiler/translator/ShaderLang.cpp b/chromium/third_party/angle/src/compiler/translator/ShaderLang.cpp index e4f27fb1b56..b6db0f0aef1 100644 --- a/chromium/third_party/angle/src/compiler/translator/ShaderLang.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ShaderLang.cpp @@ -182,6 +182,37 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) resources->MaxExpressionComplexity = 256; resources->MaxCallStackDepth = 256; resources->MaxFunctionParameters = 1024; + + // ES 3.1 Revision 4, 7.2 Built-in Constants + resources->MaxImageUnits = 4; + resources->MaxVertexImageUniforms = 0; + resources->MaxFragmentImageUniforms = 0; + resources->MaxComputeImageUniforms = 4; + resources->MaxCombinedImageUniforms = 4; + + resources->MaxCombinedShaderOutputResources = 4; + + resources->MaxComputeWorkGroupCount[0] = 65535; + resources->MaxComputeWorkGroupCount[1] = 65535; + resources->MaxComputeWorkGroupCount[2] = 65535; + resources->MaxComputeWorkGroupSize[0] = 128; + resources->MaxComputeWorkGroupSize[1] = 128; + resources->MaxComputeWorkGroupSize[2] = 64; + resources->MaxComputeUniformComponents = 512; + resources->MaxComputeTextureImageUnits = 16; + + resources->MaxComputeAtomicCounters = 8; + resources->MaxComputeAtomicCounterBuffers = 1; + + resources->MaxVertexAtomicCounters = 0; + resources->MaxFragmentAtomicCounters = 0; + resources->MaxCombinedAtomicCounters = 8; + resources->MaxAtomicCounterBindings = 1; + + resources->MaxVertexAtomicCounterBuffers = 0; + resources->MaxFragmentAtomicCounterBuffers = 0; + resources->MaxCombinedAtomicCounterBuffers = 1; + resources->MaxAtomicCounterBufferSize = 32; } // @@ -237,11 +268,10 @@ const std::string &ShGetBuiltInResourcesString(const ShHandle handle) // Return: The return value of ShCompile is really boolean, indicating // success or failure. // -bool ShCompile( - const ShHandle handle, - const char *const shaderStrings[], - size_t numStrings, - int compileOptions) +bool ShCompile(const ShHandle handle, + const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); @@ -327,18 +357,20 @@ const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handl return GetShaderVariables<sh::InterfaceBlock>(handle); } -bool ShCheckVariablesWithinPackingLimits( - int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize) +sh::WorkGroupSize ShGetComputeShaderLocalGroupSize(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast<TShHandleBase *>(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getComputeShaderLocalSize(); +} + +bool ShCheckVariablesWithinPackingLimits(int maxVectors, + const std::vector<sh::ShaderVariable> &variables) { - if (varInfoArraySize == 0) - return true; - ASSERT(varInfoArray); - std::vector<sh::ShaderVariable> variables; - for (size_t ii = 0; ii < varInfoArraySize; ++ii) - { - sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size); - variables.push_back(var); - } VariablePacker packer; return packer.CheckVariablesWithinPackingLimits(maxVectors, variables); } @@ -376,4 +408,4 @@ const std::map<std::string, unsigned int> *ShGetUniformRegisterMap(const ShHandl static std::map<std::string, unsigned int> map; return ↦ #endif // ANGLE_ENABLE_HLSL -}
\ No newline at end of file +} diff --git a/chromium/third_party/angle/src/compiler/translator/ShaderVars.cpp b/chromium/third_party/angle/src/compiler/translator/ShaderVars.cpp index 8f931b9bdd3..8e217f1c0da 100644 --- a/chromium/third_party/angle/src/compiler/translator/ShaderVars.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ShaderVars.cpp @@ -355,7 +355,7 @@ bool Varying::isSameVaryingAtLinkTime(const Varying &other) const bool Varying::isSameVaryingAtLinkTime(const Varying &other, int shaderVersion) const { return (ShaderVariable::isSameVariableAtLinkTime(other, false) && - interpolation == other.interpolation && + InterpolationTypesMatch(interpolation, other.interpolation) && (shaderVersion >= 300 || isInvariant == other.isInvariant)); } @@ -398,4 +398,91 @@ std::string InterfaceBlock::fieldPrefix() const return instanceName.empty() ? "" : name; } +bool InterfaceBlock::isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const +{ + if (name != other.name || mappedName != other.mappedName || arraySize != other.arraySize || + layout != other.layout || isRowMajorLayout != other.isRowMajorLayout || + fields.size() != other.fields.size()) + { + return false; + } + + for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex) + { + if (!fields[fieldIndex].isSameInterfaceBlockFieldAtLinkTime(other.fields[fieldIndex])) + { + return false; + } + } + + return true; +} + +void WorkGroupSize::fill(int fillValue) +{ + localSizeQualifiers[0] = fillValue; + localSizeQualifiers[1] = fillValue; + localSizeQualifiers[2] = fillValue; +} + +void WorkGroupSize::setLocalSize(int localSizeX, int localSizeY, int localSizeZ) +{ + localSizeQualifiers[0] = localSizeX; + localSizeQualifiers[1] = localSizeY; + localSizeQualifiers[2] = localSizeZ; +} + +// check that if one of them is less than 1, then all of them are. +// Or if one is positive, then all of them are positive. +bool WorkGroupSize::isLocalSizeValid() const +{ + return ( + (localSizeQualifiers[0] < 1 && localSizeQualifiers[1] < 1 && localSizeQualifiers[2] < 1) || + (localSizeQualifiers[0] > 0 && localSizeQualifiers[1] > 0 && localSizeQualifiers[2] > 0)); +} + +bool WorkGroupSize::isAnyValueSet() const +{ + return localSizeQualifiers[0] > 0 || localSizeQualifiers[1] > 0 || localSizeQualifiers[2] > 0; +} + +bool WorkGroupSize::isDeclared() const +{ + bool localSizeDeclared = localSizeQualifiers[0] > 0; + ASSERT(isLocalSizeValid()); + return localSizeDeclared; +} + +bool WorkGroupSize::isWorkGroupSizeMatching(const WorkGroupSize &right) const +{ + for (size_t i = 0u; i < size(); ++i) + { + bool result = (localSizeQualifiers[i] == right.localSizeQualifiers[i] || + (localSizeQualifiers[i] == 1 && right.localSizeQualifiers[i] == -1) || + (localSizeQualifiers[i] == -1 && right.localSizeQualifiers[i] == 1)); + if (!result) + { + return false; + } + } + return true; +} + +int &WorkGroupSize::operator[](size_t index) +{ + ASSERT(index < size()); + return localSizeQualifiers[index]; +} + +int WorkGroupSize::operator[](size_t index) const +{ + ASSERT(index < size()); + return localSizeQualifiers[index]; +} + +size_t WorkGroupSize::size() const +{ + return 3u; +} + } // namespace sh diff --git a/chromium/third_party/angle/src/compiler/translator/SimplifyLoopConditions.cpp b/chromium/third_party/angle/src/compiler/translator/SimplifyLoopConditions.cpp new file mode 100644 index 00000000000..da8da481f24 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/SimplifyLoopConditions.cpp @@ -0,0 +1,282 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SimplifyLoopConditions is an AST traverser that converts loop conditions and loop expressions +// to regular statements inside the loop. This way further transformations that generate statements +// from loop conditions and loop expressions work correctly. +// + +#include "compiler/translator/SimplifyLoopConditions.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" + +namespace +{ + +TIntermConstantUnion *CreateBoolConstantNode(bool value) +{ + TConstantUnion *u = new TConstantUnion; + u->setBConst(value); + TIntermConstantUnion *node = + new TIntermConstantUnion(u, TType(EbtBool, EbpUndefined, EvqConst, 1)); + return node; +} + +class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser +{ + public: + SimplifyLoopConditionsTraverser(unsigned int conditionsToSimplifyMask, + const TSymbolTable &symbolTable, + int shaderVersion); + + void traverseLoop(TIntermLoop *node) override; + + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + + void nextIteration(); + bool foundLoopToChange() const { return mFoundLoopToChange; } + + protected: + // Marked to true once an operation that needs to be hoisted out of the expression has been + // found. After that, no more AST updates are performed on that traversal. + bool mFoundLoopToChange; + bool mInsideLoopConditionOrExpression; + IntermNodePatternMatcher mConditionsToSimplify; +}; + +SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser( + unsigned int conditionsToSimplifyMask, + const TSymbolTable &symbolTable, + int shaderVersion) + : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion), + mFoundLoopToChange(false), + mInsideLoopConditionOrExpression(false), + mConditionsToSimplify(conditionsToSimplifyMask) +{ +} + +void SimplifyLoopConditionsTraverser::nextIteration() +{ + mFoundLoopToChange = false; + mInsideLoopConditionOrExpression = false; + nextTemporaryIndex(); +} + +bool SimplifyLoopConditionsTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + // The visit functions operate in three modes: + // 1. If a matching expression has already been found, we return early since only one loop can + // be transformed on one traversal. + // 2. We try to find loops. In case a node is not inside a loop and can not contain loops, we + // stop traversing the subtree. + // 3. If we're inside a loop condition or expression, we check for expressions that should be + // moved out of the loop condition or expression. If one is found, the loop is processed. + + if (mFoundLoopToChange) + return false; + + if (!mInsideLoopConditionOrExpression) + return false; + + mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode(), isLValueRequiredHere()); + return !mFoundLoopToChange; +} + +bool SimplifyLoopConditionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mFoundLoopToChange) + return false; + + // If we're outside a loop condition, we only need to traverse nodes that may contain loops. + if (!mInsideLoopConditionOrExpression) + return (node->getOp() == EOpSequence || node->getOp() == EOpFunction); + + mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode()); + return !mFoundLoopToChange; +} + +bool SimplifyLoopConditionsTraverser::visitTernary(Visit visit, TIntermTernary *node) +{ + if (mFoundLoopToChange) + return false; + + // Don't traverse ternary operators outside loop conditions. + if (!mInsideLoopConditionOrExpression) + return false; + + mFoundLoopToChange = mConditionsToSimplify.match(node); + return !mFoundLoopToChange; +} + +void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node) +{ + if (mFoundLoopToChange) + return; + + // Mark that we're inside a loop condition or expression, and transform the loop if needed. + + incrementDepth(node); + + // Note: No need to traverse the loop init node. + + mInsideLoopConditionOrExpression = true; + TLoopType loopType = node->getType(); + + if (node->getCondition()) + { + node->getCondition()->traverse(this); + + if (mFoundLoopToChange) + { + // Replace the loop condition with a boolean variable that's updated on each iteration. + if (loopType == ELoopWhile) + { + // Transform: + // while (expr) { body; } + // into + // bool s0 = expr; + // while (s0) { { body; } s0 = expr; } + TIntermSequence tempInitSeq; + tempInitSeq.push_back(createTempInitDeclaration(node->getCondition()->deepCopy())); + insertStatementsInParentBlock(tempInitSeq); + + TIntermAggregate *newBody = new TIntermAggregate(EOpSequence); + if (node->getBody()) + { + ASSERT(node->getBody()->getOp() == EOpSequence); + newBody->getSequence()->push_back(node->getBody()); + } + newBody->getSequence()->push_back( + createTempAssignment(node->getCondition()->deepCopy())); + + // Can't use queueReplacement to replace old body, since it may have been nullptr. + // It's safe to do the replacements in place here - this node won't be traversed + // further. + node->setBody(newBody); + node->setCondition(createTempSymbol(node->getCondition()->getType())); + } + else if (loopType == ELoopDoWhile) + { + // Transform: + // do { + // body; + // } while (expr); + // into + // bool s0 = true; + // do { + // { body; } + // s0 = expr; + // while (s0); + TIntermSequence tempInitSeq; + tempInitSeq.push_back(createTempInitDeclaration(CreateBoolConstantNode(true))); + insertStatementsInParentBlock(tempInitSeq); + + TIntermAggregate *newBody = new TIntermAggregate(EOpSequence); + if (node->getBody()) + { + ASSERT(node->getBody()->getOp() == EOpSequence); + newBody->getSequence()->push_back(node->getBody()); + } + newBody->getSequence()->push_back( + createTempAssignment(node->getCondition()->deepCopy())); + + // Can't use queueReplacement to replace old body, since it may have been nullptr. + // It's safe to do the replacements in place here - this node won't be traversed + // further. + node->setBody(newBody); + node->setCondition(createTempSymbol(node->getCondition()->getType())); + } + else if (loopType == ELoopFor) + { + // Move the loop condition inside the loop. + // Transform: + // for (init; expr; exprB) { body; } + // into + // { + // init; + // bool s0 = expr; + // while (s0) { { body; } exprB; s0 = expr; } + // } + TIntermAggregate *loopScope = new TIntermAggregate(EOpSequence); + if (node->getInit()) + { + loopScope->getSequence()->push_back(node->getInit()); + } + loopScope->getSequence()->push_back( + createTempInitDeclaration(node->getCondition()->deepCopy())); + + TIntermAggregate *whileLoopBody = new TIntermAggregate(EOpSequence); + if (node->getBody()) + { + whileLoopBody->getSequence()->push_back(node->getBody()); + } + whileLoopBody->getSequence()->push_back(node->getExpression()); + whileLoopBody->getSequence()->push_back( + createTempAssignment(node->getCondition()->deepCopy())); + TIntermLoop *whileLoop = new TIntermLoop( + ELoopWhile, nullptr, createTempSymbol(node->getCondition()->getType()), nullptr, + whileLoopBody); + loopScope->getSequence()->push_back(whileLoop); + queueReplacementWithParent(getAncestorNode(1), node, loopScope, + OriginalNode::IS_DROPPED); + } + } + } + + if (!mFoundLoopToChange && node->getExpression()) + { + node->getExpression()->traverse(this); + + if (mFoundLoopToChange) + { + ASSERT(loopType == ELoopFor); + // Move the loop expression to inside the loop. + // Transform: + // for (init; expr; exprB) { body; } + // into + // for (init; expr; ) { { body; } exprB; } + TIntermTyped *loopExpression = node->getExpression(); + node->setExpression(nullptr); + TIntermAggregate *oldBody = node->getBody(); + node->setBody(new TIntermAggregate(EOpSequence)); + if (oldBody != nullptr) + { + node->getBody()->getSequence()->push_back(oldBody); + } + node->getBody()->getSequence()->push_back(loopExpression); + } + } + + mInsideLoopConditionOrExpression = false; + + if (!mFoundLoopToChange && node->getBody()) + node->getBody()->traverse(this); + + decrementDepth(); +} + +} // namespace + +void SimplifyLoopConditions(TIntermNode *root, + unsigned int conditionsToSimplifyMask, + unsigned int *temporaryIndex, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + SimplifyLoopConditionsTraverser traverser(conditionsToSimplifyMask, symbolTable, shaderVersion); + ASSERT(temporaryIndex != nullptr); + traverser.useTemporaryIndex(temporaryIndex); + // Process one loop at a time, and reset the traverser between iterations. + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.foundLoopToChange()) + traverser.updateTree(); + } while (traverser.foundLoopToChange()); +} diff --git a/chromium/third_party/angle/src/compiler/translator/SimplifyLoopConditions.h b/chromium/third_party/angle/src/compiler/translator/SimplifyLoopConditions.h new file mode 100644 index 00000000000..b8802aa11af --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/SimplifyLoopConditions.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SimplifyLoopConditions is an AST traverser that converts loop conditions and loop expressions +// to regular statements inside the loop. This way further transformations that generate statements +// from loop conditions and loop expressions work correctly. +// + +#ifndef COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_ +#define COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_ + +class TIntermNode; +class TSymbolTable; + +void SimplifyLoopConditions(TIntermNode *root, + unsigned int conditionsToSimplify, + unsigned int *temporaryIndex, + const TSymbolTable &symbolTable, + int shaderVersion); + +#endif // COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/SplitSequenceOperator.cpp b/chromium/third_party/angle/src/compiler/translator/SplitSequenceOperator.cpp new file mode 100644 index 00000000000..ff6443d30e2 --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/SplitSequenceOperator.cpp @@ -0,0 +1,160 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SplitSequenceOperator is an AST traverser that detects sequence operator expressions that +// go through further AST transformations that generate statements, and splits them so that +// possible side effects of earlier parts of the sequence operator expression are guaranteed to be +// evaluated before the latter parts of the sequence operator expression are evaluated. +// + +#include "compiler/translator/SplitSequenceOperator.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" + +namespace +{ + +class SplitSequenceOperatorTraverser : public TLValueTrackingTraverser +{ + public: + SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask, + const TSymbolTable &symbolTable, + int shaderVersion); + + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + + void nextIteration(); + bool foundExpressionToSplit() const { return mFoundExpressionToSplit; } + + protected: + // Marked to true once an operation that needs to be hoisted out of the expression has been + // found. After that, no more AST updates are performed on that traversal. + bool mFoundExpressionToSplit; + int mInsideSequenceOperator; + + IntermNodePatternMatcher mPatternToSplitMatcher; +}; + +SplitSequenceOperatorTraverser::SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask, + const TSymbolTable &symbolTable, + int shaderVersion) + : TLValueTrackingTraverser(true, false, true, symbolTable, shaderVersion), + mFoundExpressionToSplit(false), + mInsideSequenceOperator(0), + mPatternToSplitMatcher(patternsToSplitMask) +{ +} + +void SplitSequenceOperatorTraverser::nextIteration() +{ + mFoundExpressionToSplit = false; + mInsideSequenceOperator = 0; + nextTemporaryIndex(); +} + +bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (mFoundExpressionToSplit) + return false; + + if (mInsideSequenceOperator > 0 && visit == PreVisit) + { + // Detect expressions that need to be simplified + mFoundExpressionToSplit = + mPatternToSplitMatcher.match(node, getParentNode(), isLValueRequiredHere()); + return !mFoundExpressionToSplit; + } + + return true; +} + +bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (node->getOp() == EOpComma) + { + if (visit == PreVisit) + { + if (mFoundExpressionToSplit) + { + return false; + } + mInsideSequenceOperator++; + } + else if (visit == PostVisit) + { + // Split sequence operators starting from the outermost one to preserve correct + // execution order. + if (mFoundExpressionToSplit && mInsideSequenceOperator == 1) + { + // Move all operands of the sequence operation except the last one into separate + // statements in the parent block. + TIntermSequence insertions; + for (auto *sequenceChild : *node->getSequence()) + { + if (sequenceChild != node->getSequence()->back()) + { + insertions.push_back(sequenceChild); + } + } + insertStatementsInParentBlock(insertions); + // Replace the sequence with its last operand + queueReplacement(node, node->getSequence()->back(), OriginalNode::IS_DROPPED); + } + mInsideSequenceOperator--; + } + return true; + } + + if (mFoundExpressionToSplit) + return false; + + if (mInsideSequenceOperator > 0 && visit == PreVisit) + { + // Detect expressions that need to be simplified + mFoundExpressionToSplit = mPatternToSplitMatcher.match(node, getParentNode()); + return !mFoundExpressionToSplit; + } + + return true; +} + +bool SplitSequenceOperatorTraverser::visitTernary(Visit visit, TIntermTernary *node) +{ + if (mFoundExpressionToSplit) + return false; + + if (mInsideSequenceOperator > 0 && visit == PreVisit) + { + // Detect expressions that need to be simplified + mFoundExpressionToSplit = mPatternToSplitMatcher.match(node); + return !mFoundExpressionToSplit; + } + + return true; +} + +} // namespace + +void SplitSequenceOperator(TIntermNode *root, + int patternsToSplitMask, + unsigned int *temporaryIndex, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + SplitSequenceOperatorTraverser traverser(patternsToSplitMask, symbolTable, shaderVersion); + ASSERT(temporaryIndex != nullptr); + traverser.useTemporaryIndex(temporaryIndex); + // Separate one expression at a time, and reset the traverser between iterations. + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.foundExpressionToSplit()) + traverser.updateTree(); + } while (traverser.foundExpressionToSplit()); +} diff --git a/chromium/third_party/angle/src/compiler/translator/SplitSequenceOperator.h b/chromium/third_party/angle/src/compiler/translator/SplitSequenceOperator.h new file mode 100644 index 00000000000..4a46fe36c0a --- /dev/null +++ b/chromium/third_party/angle/src/compiler/translator/SplitSequenceOperator.h @@ -0,0 +1,24 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SplitSequenceOperator is an AST traverser that detects sequence operator expressions that +// go through further AST transformations that generate statements, and splits them so that +// possible side effects of earlier parts of the sequence operator expression are guaranteed to be +// evaluated before the latter parts of the sequence operator expression are evaluated. +// + +#ifndef COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_ +#define COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_ + +class TIntermNode; +class TSymbolTable; + +void SplitSequenceOperator(TIntermNode *root, + int patternsToSplitMask, + unsigned int *temporaryIndex, + const TSymbolTable &symbolTable, + int shaderVersion); + +#endif // COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/SymbolTable.cpp b/chromium/third_party/angle/src/compiler/translator/SymbolTable.cpp index f5789091425..059c5c76ab5 100644 --- a/chromium/third_party/angle/src/compiler/translator/SymbolTable.cpp +++ b/chromium/third_party/angle/src/compiler/translator/SymbolTable.cpp @@ -88,7 +88,9 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, do { - if (level == ESSL3_BUILTINS && shaderVersion != 300) + if (level == ESSL3_1_BUILTINS && shaderVersion != 310) + level--; + if (level == ESSL3_BUILTINS && shaderVersion < 300) level--; if (level == ESSL1_BUILTINS && shaderVersion != 100) level--; @@ -110,7 +112,9 @@ TSymbol *TSymbolTable::findBuiltIn( { for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--) { - if (level == ESSL3_BUILTINS && shaderVersion != 300) + if (level == ESSL3_1_BUILTINS && shaderVersion != 310) + level--; + if (level == ESSL3_BUILTINS && shaderVersion < 300) level--; if (level == ESSL1_BUILTINS && shaderVersion != 100) level--; diff --git a/chromium/third_party/angle/src/compiler/translator/SymbolTable.h b/chromium/third_party/angle/src/compiler/translator/SymbolTable.h index 6de7c988300..f092412ad83 100644 --- a/chromium/third_party/angle/src/compiler/translator/SymbolTable.h +++ b/chromium/third_party/angle/src/compiler/translator/SymbolTable.h @@ -30,6 +30,7 @@ // are tracked in the intermediate representation, not the symbol table. // +#include <array> #include <assert.h> #include <set> @@ -295,6 +296,7 @@ class TSymbolTableLevel typedef std::pair<tLevel::iterator, bool> tInsertResult; TSymbolTableLevel() + : mGlobalInvariant(false) { } ~TSymbolTableLevel(); @@ -306,8 +308,22 @@ class TSymbolTableLevel TSymbol *find(const TString &name) const; + void addInvariantVarying(const std::string &name) + { + mInvariantVaryings.insert(name); + } + + bool isVaryingInvariant(const std::string &name) + { + return (mGlobalInvariant || mInvariantVaryings.count(name) > 0); + } + + void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; } + protected: tLevel level; + std::set<std::string> mInvariantVaryings; + bool mGlobalInvariant; }; // Define ESymbolLevel as int rather than an enum since level can go @@ -317,14 +333,14 @@ typedef int ESymbolLevel; const int COMMON_BUILTINS = 0; const int ESSL1_BUILTINS = 1; const int ESSL3_BUILTINS = 2; -const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS; -const int GLOBAL_LEVEL = 3; +const int ESSL3_1_BUILTINS = 3; +const int LAST_BUILTIN_LEVEL = ESSL3_1_BUILTINS; +const int GLOBAL_LEVEL = 4; class TSymbolTable : angle::NonCopyable { public: TSymbolTable() - : mGlobalInvariant(false) { // The symbol table cannot be used until push() is called, but // the lack of an initial call to push() can be used to detect @@ -346,7 +362,7 @@ class TSymbolTable : angle::NonCopyable } bool atGlobalLevel() const { - return currentLevel() <= GLOBAL_LEVEL; + return currentLevel() == GLOBAL_LEVEL; } void push() { @@ -379,10 +395,10 @@ class TSymbolTable : angle::NonCopyable return table[level]->insert(symbol); } - bool insertConstInt(ESymbolLevel level, const char *name, int value) + bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision) { - TVariable *constant = new TVariable( - NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); + TVariable *constant = + new TVariable(NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1)); TConstantUnion *unionArray = new TConstantUnion[1]; unionArray[0].setIConst(value); constant->shareConstPointer(unionArray); @@ -399,6 +415,24 @@ class TSymbolTable : angle::NonCopyable return insert(level, ext, constant); } + bool insertConstIvec3(ESymbolLevel level, + const char *name, + const std::array<int, 3> &values, + TPrecision precision) + { + TVariable *constantIvec3 = + new TVariable(NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3)); + + TConstantUnion *unionArray = new TConstantUnion[3]; + for (size_t index = 0u; index < 3u; ++index) + { + unionArray[index].setIConst(values[index]); + } + constantIvec3->shareConstPointer(unionArray); + + return insert(level, constantIvec3); + } + void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name, const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0); @@ -437,15 +471,15 @@ class TSymbolTable : angle::NonCopyable bool setDefaultPrecision(const TPublicType &type, TPrecision prec) { - if (!SupportsPrecision(type.type)) + if (!SupportsPrecision(type.getBasicType())) return false; - if (type.type == EbtUInt) + if (type.getBasicType() == EbtUInt) return false; // ESSL 3.00.4 section 4.5.4 if (type.isAggregate()) return false; // Not allowed to set for aggregate types int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; // Uses map operator [], overwrites the current value - (*precisionStack[indexOfLastElement])[type.type] = prec; + (*precisionStack[indexOfLastElement])[type.getBasicType()] = prec; return true; } @@ -457,7 +491,8 @@ class TSymbolTable : angle::NonCopyable // "invariant varying_name;". void addInvariantVarying(const std::string &originalName) { - mInvariantVaryings.insert(originalName); + ASSERT(atGlobalLevel()); + table[currentLevel()]->addInvariantVarying(originalName); } // If this returns false, the varying could still be invariant // if it is set as invariant during the varying variable @@ -465,12 +500,15 @@ class TSymbolTable : angle::NonCopyable // variable's type, not here. bool isVaryingInvariant(const std::string &originalName) const { - return (mGlobalInvariant || - mInvariantVaryings.count(originalName) > 0); + ASSERT(atGlobalLevel()); + return table[currentLevel()]->isVaryingInvariant(originalName); } - void setGlobalInvariant() { mGlobalInvariant = true; } - bool getGlobalInvariant() const { return mGlobalInvariant; } + void setGlobalInvariant(bool invariant) + { + ASSERT(atGlobalLevel()); + table[currentLevel()]->setGlobalInvariant(invariant); + } static int nextUniqueId() { @@ -500,9 +538,6 @@ class TSymbolTable : angle::NonCopyable std::set<std::string> mUnmangledBuiltinNames; - std::set<std::string> mInvariantVaryings; - bool mGlobalInvariant; - static int uniqueIdCounter; }; diff --git a/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.cpp index f0b48d047c8..a0719006b9e 100644 --- a/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.cpp @@ -473,22 +473,40 @@ void GetTextureReference(TInfoSinkBase &out, void OutputTextureSizeFunctionBody(TInfoSinkBase &out, const TextureFunctionHLSL::TextureFunction &textureFunction, - const TString &textureReference) + const TString &textureReference, + bool getDimensionsIgnoresBaseLevel) { - out << "int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n"; + if (getDimensionsIgnoresBaseLevel) + { + out << "int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n"; + } + else + { + out << "int baseLevel = 0;\n"; + } + if (IsSampler3D(textureFunction.sampler) || IsSamplerArray(textureFunction.sampler) || (IsIntegerSampler(textureFunction.sampler) && IsSamplerCube(textureFunction.sampler))) { // "depth" stores either the number of layers in an array texture or 3D depth out << " uint width; uint height; uint depth; uint numberOfLevels;\n" << " " << textureReference - << ".GetDimensions(baseLevel + lod, width, height, depth, numberOfLevels);\n"; + << ".GetDimensions(baseLevel, width, height, depth, numberOfLevels);\n" + << " width = max(width >> lod, 1);\n" + << " height = max(height >> lod, 1);\n"; + + if (!IsSamplerArray(textureFunction.sampler)) + { + out << " depth = max(depth >> lod, 1);\n"; + } } else if (IsSampler2D(textureFunction.sampler) || IsSamplerCube(textureFunction.sampler)) { out << " uint width; uint height; uint numberOfLevels;\n" << " " << textureReference - << ".GetDimensions(baseLevel + lod, width, height, numberOfLevels);\n"; + << ".GetDimensions(baseLevel, width, height, numberOfLevels);\n" + << " width = max(width >> lod, 1);\n" + << " height = max(height >> lod, 1);\n"; } else UNREACHABLE(); @@ -1095,32 +1113,8 @@ const char *TextureFunctionHLSL::TextureFunction::getReturnType() const bool TextureFunctionHLSL::TextureFunction::operator<(const TextureFunction &rhs) const { - if (sampler < rhs.sampler) - return true; - if (sampler > rhs.sampler) - return false; - - if (coords < rhs.coords) - return true; - if (coords > rhs.coords) - return false; - - if (!proj && rhs.proj) - return true; - if (proj && !rhs.proj) - return false; - - if (!offset && rhs.offset) - return true; - if (offset && !rhs.offset) - return false; - - if (method < rhs.method) - return true; - if (method > rhs.method) - return false; - - return false; + return std::tie(sampler, coords, proj, offset, method) < + std::tie(rhs.sampler, rhs.coords, rhs.proj, rhs.offset, rhs.method); } TString TextureFunctionHLSL::useTextureFunction(const TString &name, @@ -1249,7 +1243,9 @@ TString TextureFunctionHLSL::useTextureFunction(const TString &name, return textureFunction.name(); } -void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out, const ShShaderOutput outputType) +void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out, + const ShShaderOutput outputType, + bool getDimensionsIgnoresBaseLevel) { for (const TextureFunction &textureFunction : mUsesTexture) { @@ -1272,7 +1268,8 @@ void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out, const ShShad if (textureFunction.method == TextureFunction::SIZE) { - OutputTextureSizeFunctionBody(out, textureFunction, textureReference); + OutputTextureSizeFunctionBody(out, textureFunction, textureReference, + getDimensionsIgnoresBaseLevel); } else { diff --git a/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.h b/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.h index 6c8ce3130f5..68bf8c0898c 100644 --- a/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/TextureFunctionHLSL.h @@ -62,7 +62,9 @@ class TextureFunctionHLSL final : angle::NonCopyable bool lod0, sh::GLenum shaderType); - void textureFunctionHeader(TInfoSinkBase &out, const ShShaderOutput outputType); + void textureFunctionHeader(TInfoSinkBase &out, + const ShShaderOutput outputType, + bool getDimensionsIgnoresBaseLevel); private: typedef std::set<TextureFunction> TextureFunctionSet; diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.cpp b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.cpp index 76d006fd11d..109b1700d5d 100644 --- a/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.cpp @@ -6,7 +6,6 @@ #include "compiler/translator/TranslatorESSL.h" -#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h" #include "compiler/translator/EmulatePrecision.h" #include "compiler/translator/RecordConstantPrecision.h" #include "compiler/translator/OutputESSL.h" @@ -17,15 +16,8 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec) { } -void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) +void TranslatorESSL::translate(TIntermNode *root, ShCompileOptions compileOptions) { - if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS) - { - InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); - } -} - -void TranslatorESSL::translate(TIntermNode *root, int) { TInfoSinkBase& sink = getInfoSink().obj; int shaderVer = getShaderVersion(); @@ -34,11 +26,13 @@ void TranslatorESSL::translate(TIntermNode *root, int) { sink << "#version " << shaderVer << " es\n"; } - writePragma(); - // Write built-in extension behaviors. writeExtensionBehavior(); + // Write pragmas after extensions because some drivers consider pragmas + // like non-preprocessor tokens. + writePragma(compileOptions); + bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; if (precisionEmulation) @@ -46,7 +40,7 @@ void TranslatorESSL::translate(TIntermNode *root, int) { EmulatePrecision emulatePrecision(getSymbolTable(), shaderVer); root->traverse(&emulatePrecision); emulatePrecision.updateTree(); - emulatePrecision.writeEmulationHelpers(sink, SH_ESSL_OUTPUT); + emulatePrecision.writeEmulationHelpers(sink, shaderVer, SH_ESSL_OUTPUT); } RecordConstantPrecision(root, getTemporaryIndex()); @@ -75,12 +69,25 @@ void TranslatorESSL::translate(TIntermNode *root, int) { // Write array bounds clamping emulation if needed. getArrayBoundsClamper().OutputClampingFunctionDefinition(sink); + if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared()) + { + const sh::WorkGroupSize &localSize = getComputeShaderLocalSize(); + sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1] + << ", local_size_z=" << localSize[2] << ") in;\n"; + } + // Write translated shader. TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), shaderVer, precisionEmulation); root->traverse(&outputESSL); } +bool TranslatorESSL::shouldFlattenPragmaStdglInvariantAll() +{ + // Not necessary when translating to ESSL. + return false; +} + void TranslatorESSL::writeExtensionBehavior() { TInfoSinkBase& sink = getInfoSink().obj; const TExtensionBehavior& extBehavior = getExtensionBehavior(); diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.h b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.h index 2cc61074d48..f147ca06610 100644 --- a/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.h +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorESSL.h @@ -15,9 +15,8 @@ class TranslatorESSL : public TCompiler TranslatorESSL(sh::GLenum type, ShShaderSpec spec); protected: - void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override; - - void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermNode *root, ShCompileOptions compileOptions) override; + bool shouldFlattenPragmaStdglInvariantAll() override; private: void writeExtensionBehavior(); diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.cpp b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.cpp index a05802fbcda..a0ee01f55b8 100644 --- a/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.cpp @@ -11,6 +11,7 @@ #include "compiler/translator/EmulatePrecision.h" #include "compiler/translator/ExtensionGLSL.h" #include "compiler/translator/OutputGLSL.h" +#include "compiler/translator/RewriteTexelFetchOffset.h" #include "compiler/translator/VersionGLSL.h" TranslatorGLSL::TranslatorGLSL(sh::GLenum type, @@ -19,29 +20,73 @@ TranslatorGLSL::TranslatorGLSL(sh::GLenum type, : TCompiler(type, spec, output) { } -void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) +void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions) { - if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS) + if (compileOptions & SH_EMULATE_ABS_INT_FUNCTION) { - InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + } + + if (compileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION) + { + InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(emu, getShaderVersion()); } int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType()); InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion); } -void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) +void TranslatorGLSL::translate(TIntermNode *root, ShCompileOptions compileOptions) { TInfoSinkBase& sink = getInfoSink().obj; // Write GLSL version. writeVersion(root); - writePragma(); - // Write extension behaviour as needed writeExtensionBehavior(root); + // Write pragmas after extensions because some drivers consider pragmas + // like non-preprocessor tokens. + writePragma(compileOptions); + + // If flattening the global invariant pragma, write invariant declarations for built-in + // variables. It should be harmless to do this twice in the case that the shader also explicitly + // did this. However, it's important to emit invariant qualifiers only for those built-in + // variables that are actually used, to avoid affecting the behavior of the shader. + if ((compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) && getPragma().stdgl.invariantAll) + { + collectVariables(root); + + switch (getShaderType()) + { + case GL_VERTEX_SHADER: + sink << "invariant gl_Position;\n"; + + // gl_PointSize should be declared invariant in both ESSL 1.00 and 3.00 fragment + // shaders if it's statically referenced. + conditionallyOutputInvariantDeclaration("gl_PointSize"); + break; + case GL_FRAGMENT_SHADER: + // The preprocessor will reject this pragma if it's used in ESSL 3.00 fragment + // shaders, so we can use simple logic to determine whether to declare these + // variables invariant. + conditionallyOutputInvariantDeclaration("gl_FragCoord"); + conditionallyOutputInvariantDeclaration("gl_PointCoord"); + break; + default: + // Currently not reached, but leave this in for future expansion. + ASSERT(false); + break; + } + } + + if ((compileOptions & SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH) != 0) + { + sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion()); + } + bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; if (precisionEmulation) @@ -49,7 +94,7 @@ void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) EmulatePrecision emulatePrecision(getSymbolTable(), getShaderVersion()); root->traverse(&emulatePrecision); emulatePrecision.updateTree(); - emulatePrecision.writeEmulationHelpers(sink, getOutputType()); + emulatePrecision.writeEmulationHelpers(sink, getShaderVersion(), getOutputType()); } // Write emulated built-in functions if needed. @@ -132,6 +177,13 @@ void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) } } + if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared()) + { + const sh::WorkGroupSize &localSize = getComputeShaderLocalSize(); + sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1] + << ", local_size_z=" << localSize[2] << ") in;\n"; + } + // Write translated shader. TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), @@ -143,6 +195,13 @@ void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) root->traverse(&outputGLSL); } +bool TranslatorGLSL::shouldFlattenPragmaStdglInvariantAll() +{ + // Required when outputting to any GLSL version greater than 1.20, but since ANGLE doesn't + // translate to that version, return true for the next higher version. + return IsGLSL130OrNewer(getOutputType()); +} + void TranslatorGLSL::writeVersion(TIntermNode *root) { TVersionGLSL versionGLSL(getShaderType(), getPragma(), getOutputType()); @@ -221,3 +280,12 @@ void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) sink << "#extension " << ext << " : require\n"; } } + +void TranslatorGLSL::conditionallyOutputInvariantDeclaration(const char *builtinVaryingName) +{ + if (isVaryingDefined(builtinVaryingName)) + { + TInfoSinkBase &sink = getInfoSink().obj; + sink << "invariant " << builtinVaryingName << ";\n"; + } +} diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.h b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.h index 4f07b219800..f234c18eca2 100644 --- a/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorGLSL.h @@ -15,13 +15,16 @@ class TranslatorGLSL : public TCompiler TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); protected: - void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override; + void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions) override; - void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermNode *root, ShCompileOptions compileOptions) override; + bool shouldFlattenPragmaStdglInvariantAll() override; private: void writeVersion(TIntermNode *root); void writeExtensionBehavior(TIntermNode *root); + void conditionallyOutputInvariantDeclaration(const char *builtinVaryingName); }; #endif // COMPILER_TRANSLATOR_TRANSLATORGLSL_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.cpp index 111a38b7ede..fb011da7667 100644 --- a/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.cpp @@ -6,13 +6,22 @@ #include "compiler/translator/TranslatorHLSL.h" +#include "compiler/translator/AddDefaultReturnStatements.h" #include "compiler/translator/ArrayReturnValueToOutParameter.h" +#include "compiler/translator/BreakVariableAliasingInInnerLoops.h" +#include "compiler/translator/EmulatePrecision.h" +#include "compiler/translator/ExpandIntegerPowExpressions.h" +#include "compiler/translator/IntermNodePatternMatcher.h" #include "compiler/translator/OutputHLSL.h" #include "compiler/translator/RemoveDynamicIndexing.h" #include "compiler/translator/RewriteElseBlocks.h" +#include "compiler/translator/RewriteTexelFetchOffset.h" +#include "compiler/translator/RewriteUnaryMinusOperatorInt.h" #include "compiler/translator/SeparateArrayInitialization.h" #include "compiler/translator/SeparateDeclarations.h" #include "compiler/translator/SeparateExpressionsReturningArrays.h" +#include "compiler/translator/SimplifyLoopConditions.h" +#include "compiler/translator/SplitSequenceOperator.h" #include "compiler/translator/UnfoldShortCircuitToIf.h" TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) @@ -20,13 +29,29 @@ TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutpu { } -void TranslatorHLSL::translate(TIntermNode *root, int compileOptions) +void TranslatorHLSL::translate(TIntermNode *root, ShCompileOptions compileOptions) { const ShBuiltInResources &resources = getResources(); int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; + sh::AddDefaultReturnStatements(root); + SeparateDeclarations(root); + // Note that SimplifyLoopConditions needs to be run before any other AST transformations that + // may need to generate new statements from loop conditions or loop expressions. + SimplifyLoopConditions(root, + IntermNodePatternMatcher::kExpressionReturningArray | + IntermNodePatternMatcher::kUnfoldedShortCircuitExpression | + IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue, + getTemporaryIndex(), getSymbolTable(), getShaderVersion()); + + SplitSequenceOperator(root, + IntermNodePatternMatcher::kExpressionReturningArray | + IntermNodePatternMatcher::kUnfoldedShortCircuitExpression | + IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue, + getTemporaryIndex(), getSymbolTable(), getShaderVersion()); + // Note that SeparateDeclarations needs to be run before UnfoldShortCircuitToIf. UnfoldShortCircuitToIf(root, getTemporaryIndex()); @@ -52,6 +77,40 @@ void TranslatorHLSL::translate(TIntermNode *root, int compileOptions) sh::RewriteElseBlocks(root, getTemporaryIndex()); } + // Work around an HLSL compiler frontend aliasing optimization bug. + // TODO(cwallez) The date is 2016-08-25, Microsoft said the bug would be fixed + // in the next release of d3dcompiler.dll, it would be nice to detect the DLL + // version and only apply the workaround if it is too old. + sh::BreakVariableAliasingInInnerLoops(root); + + bool precisionEmulation = + getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; + + if (precisionEmulation) + { + EmulatePrecision emulatePrecision(getSymbolTable(), getShaderVersion()); + root->traverse(&emulatePrecision); + emulatePrecision.updateTree(); + emulatePrecision.writeEmulationHelpers(getInfoSink().obj, getShaderVersion(), + getOutputType()); + } + + if ((compileOptions & SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS) != 0) + { + sh::ExpandIntegerPowExpressions(root, getTemporaryIndex()); + } + + if ((compileOptions & SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH) != 0) + { + sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion()); + } + + if (((compileOptions & SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR) != 0) && + getShaderType() == GL_VERTEX_SHADER) + { + sh::RewriteUnaryMinusOperatorInt(root); + } + sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), compileOptions); @@ -61,6 +120,12 @@ void TranslatorHLSL::translate(TIntermNode *root, int compileOptions) mUniformRegisterMap = outputHLSL.getUniformRegisterMap(); } +bool TranslatorHLSL::shouldFlattenPragmaStdglInvariantAll() +{ + // Not necessary when translating to HLSL. + return false; +} + bool TranslatorHLSL::hasInterfaceBlock(const std::string &interfaceBlockName) const { return (mInterfaceBlockRegisterMap.count(interfaceBlockName) > 0); @@ -75,4 +140,4 @@ unsigned int TranslatorHLSL::getInterfaceBlockRegister(const std::string &interf const std::map<std::string, unsigned int> *TranslatorHLSL::getUniformRegisterMap() const { return &mUniformRegisterMap; -}
\ No newline at end of file +} diff --git a/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.h b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.h index 40cfd70f7b6..213d8606822 100644 --- a/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.h +++ b/chromium/third_party/angle/src/compiler/translator/TranslatorHLSL.h @@ -21,10 +21,11 @@ class TranslatorHLSL : public TCompiler const std::map<std::string, unsigned int> *getUniformRegisterMap() const; protected: - void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermNode *root, ShCompileOptions compileOptions) override; + bool shouldFlattenPragmaStdglInvariantAll() override; // collectVariables needs to be run always so registers can be assigned. - bool shouldCollectVariables(int compileOptions) override { return true; } + bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; } std::map<std::string, unsigned int> mInterfaceBlockRegisterMap; std::map<std::string, unsigned int> mUniformRegisterMap; diff --git a/chromium/third_party/angle/src/compiler/translator/Types.cpp b/chromium/third_party/angle/src/compiler/translator/Types.cpp index dffdd370aee..a1dac123aed 100644 --- a/chromium/third_party/angle/src/compiler/translator/Types.cpp +++ b/chromium/third_party/angle/src/compiler/translator/Types.cpp @@ -11,6 +11,7 @@ #include "compiler/translator/Types.h" #include "compiler/translator/InfoSink.h" #include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolTable.h" #include <algorithm> #include <climits> @@ -48,12 +49,20 @@ const char* getBasicString(TBasicType t) } TType::TType(const TPublicType &p) - : type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant), - layoutQualifier(p.layoutQualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), - array(p.array), arraySize(p.arraySize), interfaceBlock(0), structure(0) + : type(p.getBasicType()), + precision(p.precision), + qualifier(p.qualifier), + invariant(p.invariant), + layoutQualifier(p.layoutQualifier), + primarySize(p.getPrimarySize()), + secondarySize(p.getSecondarySize()), + array(p.array), + arraySize(p.arraySize), + interfaceBlock(0), + structure(0) { - if (p.userDef) - structure = p.userDef->getStruct(); + if (p.getUserDef()) + structure = p.getUserDef()->getStruct(); } bool TStructure::equals(const TStructure &other) const @@ -61,6 +70,122 @@ bool TStructure::equals(const TStructure &other) const return (uniqueId() == other.uniqueId()); } +const char *TType::getBuiltInTypeNameString() const +{ + if (isMatrix()) + { + switch (getCols()) + { + case 2: + switch (getRows()) + { + case 2: + return "mat2"; + case 3: + return "mat2x3"; + case 4: + return "mat2x4"; + default: + UNREACHABLE(); + return nullptr; + } + case 3: + switch (getRows()) + { + case 2: + return "mat3x2"; + case 3: + return "mat3"; + case 4: + return "mat3x4"; + default: + UNREACHABLE(); + return nullptr; + } + case 4: + switch (getRows()) + { + case 2: + return "mat4x2"; + case 3: + return "mat4x3"; + case 4: + return "mat4"; + default: + UNREACHABLE(); + return nullptr; + } + default: + UNREACHABLE(); + return nullptr; + } + } + if (isVector()) + { + switch (getBasicType()) + { + case EbtFloat: + switch (getNominalSize()) + { + case 2: + return "vec2"; + case 3: + return "vec3"; + case 4: + return "vec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtInt: + switch (getNominalSize()) + { + case 2: + return "ivec2"; + case 3: + return "ivec3"; + case 4: + return "ivec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtBool: + switch (getNominalSize()) + { + case 2: + return "bvec2"; + case 3: + return "bvec3"; + case 4: + return "bvec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtUInt: + switch (getNominalSize()) + { + case 2: + return "uvec2"; + case 3: + return "uvec3"; + case 4: + return "uvec4"; + default: + UNREACHABLE(); + return nullptr; + } + default: + UNREACHABLE(); + return nullptr; + } + } + ASSERT(getBasicType() != EbtStruct); + ASSERT(getBasicType() != EbtInterfaceBlock); + return getBasicString(); +} + TString TType::getCompleteString() const { TStringStream stream; @@ -202,7 +327,9 @@ size_t TType::getObjectSize() const if (isArray()) { - // TODO: getArraySize() returns an int, not a size_t + if (totalSize == 0) + return 0; + size_t currentArraySize = getArraySize(); if (currentArraySize > INT_MAX / totalSize) totalSize = INT_MAX; @@ -213,6 +340,14 @@ size_t TType::getObjectSize() const return totalSize; } +TStructure::TStructure(const TString *name, TFieldList *fields) + : TFieldListCollection(name, fields), + mDeepestNesting(0), + mUniqueId(TSymbolTable::nextUniqueId()), + mAtGlobalScope(false) +{ +} + bool TStructure::containsArrays() const { for (size_t i = 0; i < mFields->size(); ++i) @@ -248,7 +383,7 @@ bool TStructure::containsSamplers() const void TStructure::createSamplerSymbols(const TString &structName, const TString &structAPIName, - const int arrayOfStructsSize, + const unsigned int arrayOfStructsSize, TVector<TIntermSymbol *> *outputSymbols, TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const { @@ -257,9 +392,9 @@ void TStructure::createSamplerSymbols(const TString &structName, const TType *fieldType = field->type(); if (IsSampler(fieldType->getBasicType())) { - if (arrayOfStructsSize > 0) + if (arrayOfStructsSize > 0u) { - for (int arrayIndex = 0; arrayIndex < arrayOfStructsSize; ++arrayIndex) + for (unsigned int arrayIndex = 0u; arrayIndex < arrayOfStructsSize; ++arrayIndex) { TStringStream name; name << structName << "_" << arrayIndex << "_" << field->name(); @@ -289,10 +424,11 @@ void TStructure::createSamplerSymbols(const TString &structName, } else if (fieldType->isStructureContainingSamplers()) { - int nestedArrayOfStructsSize = fieldType->isArray() ? fieldType->getArraySize() : 0; + unsigned int nestedArrayOfStructsSize = + fieldType->isArray() ? fieldType->getArraySize() : 0u; if (arrayOfStructsSize > 0) { - for (int arrayIndex = 0; arrayIndex < arrayOfStructsSize; ++arrayIndex) + for (unsigned int arrayIndex = 0u; arrayIndex < arrayOfStructsSize; ++arrayIndex) { TStringStream fieldName; fieldName << structName << "_" << arrayIndex << "_" << field->name(); diff --git a/chromium/third_party/angle/src/compiler/translator/Types.h b/chromium/third_party/angle/src/compiler/translator/Types.h index ee14aa7a3b2..ab1b6c3ff77 100644 --- a/chromium/third_party/angle/src/compiler/translator/Types.h +++ b/chromium/third_party/angle/src/compiler/translator/Types.h @@ -103,13 +103,7 @@ class TStructure : public TFieldListCollection { public: POOL_ALLOCATOR_NEW_DELETE(); - TStructure(const TString *name, TFieldList *fields) - : TFieldListCollection(name, fields), - mDeepestNesting(0), - mUniqueId(0), - mAtGlobalScope(false) - { - } + TStructure(const TString *name, TFieldList *fields); int deepestNesting() const { @@ -123,7 +117,7 @@ class TStructure : public TFieldListCollection void createSamplerSymbols(const TString &structName, const TString &structAPIName, - const int arrayOfStructsSize, + const unsigned int arrayOfStructsSize, TVector<TIntermSymbol *> *outputSymbols, TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const; @@ -326,6 +320,8 @@ class TType return invariant; } + void setInvariant(bool i) { invariant = i; } + TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; @@ -387,13 +383,10 @@ class TType } bool isUnsizedArray() const { - return array && arraySize == 0; + return array && arraySize == 0u; } - int getArraySize() const - { - return arraySize; - } - void setArraySize(int s) + unsigned int getArraySize() const { return arraySize; } + void setArraySize(unsigned int s) { if (!array || arraySize != s) { @@ -407,7 +400,7 @@ class TType if (array) { array = false; - arraySize = 0; + arraySize = 0u; invalidateMangledName(); } } @@ -508,6 +501,7 @@ class TType { return ::getBasicString(type); } + const char *getPrecisionString() const { return ::getPrecisionString(precision); @@ -516,6 +510,9 @@ class TType { return ::getQualifierString(qualifier); } + + const char *getBuiltInTypeNameString() const; + TString getCompleteString() const; // If this type is a struct, returns the deepest struct nesting of @@ -552,7 +549,7 @@ class TType void createSamplerSymbols(const TString &structName, const TString &structAPIName, - const int arrayOfStructsSize, + const unsigned int arrayOfStructsSize, TVector<TIntermSymbol *> *outputSymbols, TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const { @@ -580,7 +577,7 @@ class TType unsigned char primarySize; // size of vector or cols matrix unsigned char secondarySize; // rows of a matrix bool array; - int arraySize; + unsigned int arraySize; // 0 unless this is an interface block, or interface block member variable TInterfaceBlock *interfaceBlock; @@ -591,44 +588,25 @@ class TType mutable TString mangled; }; -// -// This is a workaround for a problem with the yacc stack, It can't have -// types that it thinks have non-trivial constructors. It should -// just be used while recognizing the grammar, not anything else. Pointers -// could be used, but also trying to avoid lots of memory management overhead. -// -// Not as bad as it looks, there is no actual assumption that the fields -// match up or are name the same or anything like that. -// -struct TPublicType +// TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the +// grammar +struct TTypeSpecifierNonArray { TBasicType type; - TLayoutQualifier layoutQualifier; - TQualifier qualifier; - bool invariant; - TPrecision precision; unsigned char primarySize; // size of vector or cols of matrix unsigned char secondarySize; // rows of matrix - bool array; - int arraySize; TType *userDef; TSourceLoc line; // true if the type was defined by a struct specifier rather than a reference to a type name. bool isStructSpecifier; - void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln) + void initialize(TBasicType bt, const TSourceLoc &ln) { type = bt; - layoutQualifier = TLayoutQualifier::create(); - qualifier = q; - invariant = false; - precision = EbpUndefined; primarySize = 1; secondarySize = 1; - array = false; - arraySize = 0; - userDef = 0; + userDef = nullptr; line = ln; isStructSpecifier = false; } @@ -638,78 +616,99 @@ struct TPublicType primarySize = size; } - void setMatrix(unsigned char c, unsigned char r) + void setMatrix(unsigned char columns, unsigned char rows) { - ASSERT(c > 1 && r > 1 && c <= 4 && r <= 4); - primarySize = c; - secondarySize = r; + ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4); + primarySize = columns; + secondarySize = rows; } - bool isUnsizedArray() const - { - return array && arraySize == 0; - } - void setArraySize(int s) + bool isMatrix() const { return primarySize > 1 && secondarySize > 1; } + + bool isVector() const { return primarySize > 1 && secondarySize == 1; } +}; + +// +// This is a workaround for a problem with the yacc stack, It can't have +// types that it thinks have non-trivial constructors. It should +// just be used while recognizing the grammar, not anything else. Pointers +// could be used, but also trying to avoid lots of memory management overhead. +// +// Not as bad as it looks, there is no actual assumption that the fields +// match up or are name the same or anything like that. +// +struct TPublicType +{ + TTypeSpecifierNonArray typeSpecifierNonArray; + TLayoutQualifier layoutQualifier; + TQualifier qualifier; + bool invariant; + TPrecision precision; + bool array; + int arraySize; + + void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q) { - array = true; - arraySize = s; + typeSpecifierNonArray = typeSpecifier; + layoutQualifier = TLayoutQualifier::create(); + qualifier = q; + invariant = false; + precision = EbpUndefined; + array = false; + arraySize = 0; } - void clearArrayness() + + TBasicType getBasicType() const { return typeSpecifierNonArray.type; } + void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; } + + unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; } + unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; } + void initializeSizeForScalarTypes() { - array = false; - arraySize = 0; + typeSpecifierNonArray.primarySize = 1; + typeSpecifierNonArray.secondarySize = 1; } + const TType *getUserDef() const { return typeSpecifierNonArray.userDef; } + const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; } + + bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; } + bool isStructureContainingArrays() const { - if (!userDef) + if (!typeSpecifierNonArray.userDef) { return false; } - return userDef->isStructureContainingArrays(); + return typeSpecifierNonArray.userDef->isStructureContainingArrays(); } bool isStructureContainingType(TBasicType t) const { - if (!userDef) + if (!typeSpecifierNonArray.userDef) { return false; } - return userDef->isStructureContainingType(t); - } - - bool isMatrix() const - { - return primarySize > 1 && secondarySize > 1; + return typeSpecifierNonArray.userDef->isStructureContainingType(t); } - bool isVector() const - { - return primarySize > 1 && secondarySize == 1; - } - - int getCols() const - { - ASSERT(isMatrix()); - return primarySize; - } - - int getRows() const + bool isUnsizedArray() const { return array && arraySize == 0; } + void setArraySize(int s) { - ASSERT(isMatrix()); - return secondarySize; + array = true; + arraySize = s; } - - int getNominalSize() const + void clearArrayness() { - return primarySize; + array = false; + arraySize = 0; } bool isAggregate() const { - return array || isMatrix() || isVector(); + return array || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector(); } }; diff --git a/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp index e50bf202efd..e57681edad6 100644 --- a/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp +++ b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp @@ -10,32 +10,30 @@ namespace { // "x || y" is equivalent to "x ? true : y". -TIntermSelection *UnfoldOR(TIntermTyped *x, TIntermTyped *y) +TIntermTernary *UnfoldOR(TIntermTyped *x, TIntermTyped *y) { - const TType boolType(EbtBool, EbpUndefined); TConstantUnion *u = new TConstantUnion; u->setBConst(true); TIntermConstantUnion *trueNode = new TIntermConstantUnion( u, TType(EbtBool, EbpUndefined, EvqConst, 1)); - return new TIntermSelection(x, trueNode, y, boolType); + return new TIntermTernary(x, trueNode, y); } // "x && y" is equivalent to "x ? y : false". -TIntermSelection *UnfoldAND(TIntermTyped *x, TIntermTyped *y) +TIntermTernary *UnfoldAND(TIntermTyped *x, TIntermTyped *y) { - const TType boolType(EbtBool, EbpUndefined); TConstantUnion *u = new TConstantUnion; u->setBConst(false); TIntermConstantUnion *falseNode = new TIntermConstantUnion( u, TType(EbtBool, EbpUndefined, EvqConst, 1)); - return new TIntermSelection(x, y, falseNode, boolType); + return new TIntermTernary(x, y, falseNode); } } // namespace anonymous bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node) { - TIntermSelection *replacement = NULL; + TIntermTernary *replacement = nullptr; switch (node->getOp()) { @@ -50,8 +48,7 @@ bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node) } if (replacement) { - mReplacements.push_back( - NodeUpdateEntry(getParentNode(), node, replacement, false)); + queueReplacement(node, replacement, OriginalNode::IS_DROPPED); } return true; } diff --git a/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp index be23b524d75..f6e9a2ec3ed 100644 --- a/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp +++ b/chromium/third_party/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp @@ -11,6 +11,7 @@ #include "compiler/translator/UnfoldShortCircuitToIf.h" #include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" namespace { @@ -22,41 +23,23 @@ class UnfoldShortCircuitTraverser : public TIntermTraverser UnfoldShortCircuitTraverser(); bool visitBinary(Visit visit, TIntermBinary *node) override; - bool visitAggregate(Visit visit, TIntermAggregate *node) override; - bool visitSelection(Visit visit, TIntermSelection *node) override; - bool visitLoop(Visit visit, TIntermLoop *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; void nextIteration(); bool foundShortCircuit() const { return mFoundShortCircuit; } protected: - // Check if the traversal is inside a loop condition or expression, in which case the unfolded - // expression needs to be copied inside the loop. Returns true if the copying is done, in which - // case no further unfolding should be done on the same traversal. - // The parameters are the node that will be unfolded to multiple statements and so can't remain - // inside a loop condition, and its parent. - bool copyLoopConditionOrExpression(TIntermNode *parent, TIntermTyped *node); - // Marked to true once an operation that needs to be unfolded has been found. // After that, no more unfolding is performed on that traversal. bool mFoundShortCircuit; - // Set to the loop node while a loop condition or expression is being traversed. - TIntermLoop *mParentLoop; - // Parent of the loop node while a loop condition or expression is being traversed. - TIntermNode *mLoopParent; - - bool mInLoopCondition; - bool mInLoopExpression; + IntermNodePatternMatcher mPatternToUnfoldMatcher; }; UnfoldShortCircuitTraverser::UnfoldShortCircuitTraverser() : TIntermTraverser(true, false, true), mFoundShortCircuit(false), - mParentLoop(nullptr), - mLoopParent(nullptr), - mInLoopCondition(false), - mInLoopExpression(false) + mPatternToUnfoldMatcher(IntermNodePatternMatcher::kUnfoldedShortCircuitExpression) { } @@ -64,282 +47,115 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) { if (mFoundShortCircuit) return false; + + if (visit != PreVisit) + return true; + + if (!mPatternToUnfoldMatcher.match(node, getParentNode())) + return true; + // If our right node doesn't have side effects, we know we don't need to unfold this // expression: there will be no short-circuiting side effects to avoid // (note: unfolding doesn't depend on the left node -- it will always be evaluated) - if (!node->getRight()->hasSideEffects()) - { - return true; - } + ASSERT(node->getRight()->hasSideEffects()); + + mFoundShortCircuit = true; switch (node->getOp()) { case EOpLogicalOr: - mFoundShortCircuit = true; - if (!copyLoopConditionOrExpression(getParentNode(), node)) - { - // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; - // else s = y;", - // and then further simplifies down to "bool s = x; if(!s) s = y;". + { + // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; + // else s = y;", + // and then further simplifies down to "bool s = x; if(!s) s = y;". - TIntermSequence insertions; - TType boolType(EbtBool, EbpUndefined, EvqTemporary); + TIntermSequence insertions; + TType boolType(EbtBool, EbpUndefined, EvqTemporary); - ASSERT(node->getLeft()->getType() == boolType); - insertions.push_back(createTempInitDeclaration(node->getLeft())); + ASSERT(node->getLeft()->getType() == boolType); + insertions.push_back(createTempInitDeclaration(node->getLeft())); - TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); - ASSERT(node->getRight()->getType() == boolType); - assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); + TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); + ASSERT(node->getRight()->getType() == boolType); + assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); - TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, boolType); - notTempSymbol->setOperand(createTempSymbol(boolType)); - TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr); - insertions.push_back(ifNode); + TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, createTempSymbol(boolType)); + TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr); + insertions.push_back(ifNode); - insertStatementsInParentBlock(insertions); + insertStatementsInParentBlock(insertions); - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); - mReplacements.push_back(replaceVariable); - } - return false; + queueReplacement(node, createTempSymbol(boolType), OriginalNode::IS_DROPPED); + return false; + } case EOpLogicalAnd: - mFoundShortCircuit = true; - if (!copyLoopConditionOrExpression(getParentNode(), node)) - { - // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; - // else s = false;", - // and then further simplifies down to "bool s = x; if(s) s = y;". - TIntermSequence insertions; - TType boolType(EbtBool, EbpUndefined, EvqTemporary); - - ASSERT(node->getLeft()->getType() == boolType); - insertions.push_back(createTempInitDeclaration(node->getLeft())); - - TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); - ASSERT(node->getRight()->getType() == boolType); - assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); - - TIntermSelection *ifNode = new TIntermSelection(createTempSymbol(boolType), assignRightBlock, nullptr); - insertions.push_back(ifNode); - - insertStatementsInParentBlock(insertions); - - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); - mReplacements.push_back(replaceVariable); - } - return false; + { + // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; + // else s = false;", + // and then further simplifies down to "bool s = x; if(s) s = y;". + TIntermSequence insertions; + TType boolType(EbtBool, EbpUndefined, EvqTemporary); + + ASSERT(node->getLeft()->getType() == boolType); + insertions.push_back(createTempInitDeclaration(node->getLeft())); + + TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); + ASSERT(node->getRight()->getType() == boolType); + assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); + + TIntermIfElse *ifNode = + new TIntermIfElse(createTempSymbol(boolType), assignRightBlock, nullptr); + insertions.push_back(ifNode); + + insertStatementsInParentBlock(insertions); + + queueReplacement(node, createTempSymbol(boolType), OriginalNode::IS_DROPPED); + return false; + } default: - return true; + UNREACHABLE(); + return true; } } -bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection *node) +bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node) { if (mFoundShortCircuit) return false; + if (visit != PreVisit) + return true; + + if (!mPatternToUnfoldMatcher.match(node)) + return true; + + mFoundShortCircuit = true; + // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" - if (visit == PreVisit && node->usesTernaryOperator()) - { - mFoundShortCircuit = true; - if (!copyLoopConditionOrExpression(getParentNode(), node)) - { - TIntermSequence insertions; - - TIntermSymbol *tempSymbol = createTempSymbol(node->getType()); - TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); - tempDeclaration->getSequence()->push_back(tempSymbol); - insertions.push_back(tempDeclaration); - - TIntermAggregate *trueBlock = new TIntermAggregate(EOpSequence); - TIntermBinary *trueAssignment = - createTempAssignment(node->getTrueBlock()->getAsTyped()); - trueBlock->getSequence()->push_back(trueAssignment); - - TIntermAggregate *falseBlock = new TIntermAggregate(EOpSequence); - TIntermBinary *falseAssignment = - createTempAssignment(node->getFalseBlock()->getAsTyped()); - falseBlock->getSequence()->push_back(falseAssignment); - - TIntermSelection *ifNode = - new TIntermSelection(node->getCondition()->getAsTyped(), trueBlock, falseBlock); - insertions.push_back(ifNode); - - insertStatementsInParentBlock(insertions); - - TIntermSymbol *ternaryResult = createTempSymbol(node->getType()); - NodeUpdateEntry replaceVariable(getParentNode(), node, ternaryResult, false); - mReplacements.push_back(replaceVariable); - } - return false; - } + TIntermSequence insertions; - return true; -} + TIntermSymbol *tempSymbol = createTempSymbol(node->getType()); + TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); + tempDeclaration->getSequence()->push_back(tempSymbol); + insertions.push_back(tempDeclaration); -bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *node) -{ - if (visit == PreVisit && mFoundShortCircuit) - return false; // No need to traverse further + TIntermAggregate *trueBlock = new TIntermAggregate(EOpSequence); + TIntermBinary *trueAssignment = createTempAssignment(node->getTrueExpression()); + trueBlock->getSequence()->push_back(trueAssignment); - if (node->getOp() == EOpComma) - { - ASSERT(visit != PreVisit || !mFoundShortCircuit); - - if (visit == PostVisit && mFoundShortCircuit) - { - // We can be sure that we arrived here because there was a short-circuiting operator - // inside the sequence operator since we only start traversing the sequence operator in - // case a short-circuiting operator has not been found so far. - // We need to unfold the sequence (comma) operator, otherwise the evaluation order of - // statements would be messed up by unfolded operations inside. - // Don't do any other unfolding on this round of traversal. - mReplacements.clear(); - mMultiReplacements.clear(); - mInsertions.clear(); - - if (!copyLoopConditionOrExpression(getParentNode(), node)) - { - TIntermSequence insertions; - TIntermSequence *seq = node->getSequence(); - - TIntermSequence::size_type i = 0; - ASSERT(!seq->empty()); - while (i < seq->size() - 1) - { - TIntermTyped *child = (*seq)[i]->getAsTyped(); - insertions.push_back(child); - ++i; - } - - insertStatementsInParentBlock(insertions); - - NodeUpdateEntry replaceVariable(getParentNode(), node, (*seq)[i], false); - mReplacements.push_back(replaceVariable); - } - } - } - return true; -} + TIntermAggregate *falseBlock = new TIntermAggregate(EOpSequence); + TIntermBinary *falseAssignment = createTempAssignment(node->getFalseExpression()); + falseBlock->getSequence()->push_back(falseAssignment); -bool UnfoldShortCircuitTraverser::visitLoop(Visit visit, TIntermLoop *node) -{ - if (visit == PreVisit) - { - if (mFoundShortCircuit) - return false; // No need to traverse further - - mLoopParent = getParentNode(); - mParentLoop = node; - incrementDepth(node); - - if (node->getInit()) - { - node->getInit()->traverse(this); - if (mFoundShortCircuit) - { - decrementDepth(); - return false; - } - } - - if (node->getCondition()) - { - mInLoopCondition = true; - node->getCondition()->traverse(this); - mInLoopCondition = false; - - if (mFoundShortCircuit) - { - decrementDepth(); - return false; - } - } - - if (node->getExpression()) - { - mInLoopExpression = true; - node->getExpression()->traverse(this); - mInLoopExpression = false; - - if (mFoundShortCircuit) - { - decrementDepth(); - return false; - } - } - - if (node->getBody()) - node->getBody()->traverse(this); - - decrementDepth(); - } - return false; -} + TIntermIfElse *ifNode = + new TIntermIfElse(node->getCondition()->getAsTyped(), trueBlock, falseBlock); + insertions.push_back(ifNode); -bool UnfoldShortCircuitTraverser::copyLoopConditionOrExpression(TIntermNode *parent, - TIntermTyped *node) -{ - if (mInLoopCondition) - { - mReplacements.push_back( - NodeUpdateEntry(parent, node, createTempSymbol(node->getType()), false)); - TIntermAggregate *body = mParentLoop->getBody(); - TIntermSequence empty; - if (mParentLoop->getType() == ELoopDoWhile) - { - // Declare the temporary variable before the loop. - TIntermSequence insertionsBeforeLoop; - insertionsBeforeLoop.push_back(createTempDeclaration(node->getType())); - insertStatementsInParentBlock(insertionsBeforeLoop); - - // Move a part of do-while loop condition to inside the loop. - TIntermSequence insertionsInLoop; - insertionsInLoop.push_back(createTempAssignment(node)); - mInsertions.push_back(NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, - empty, insertionsInLoop)); - } - else - { - // The loop initializer expression and one copy of the part of the loop condition are - // executed before the loop. They need to be in a new scope. - TIntermAggregate *loopScope = new TIntermAggregate(EOpSequence); - - TIntermNode *initializer = mParentLoop->getInit(); - if (initializer != nullptr) - { - // Move the initializer to the newly created outer scope, so that condition can - // depend on it. - mReplacements.push_back(NodeUpdateEntry(mParentLoop, initializer, nullptr, false)); - loopScope->getSequence()->push_back(initializer); - } - - loopScope->getSequence()->push_back(createTempInitDeclaration(node)); - loopScope->getSequence()->push_back(mParentLoop); - mReplacements.push_back(NodeUpdateEntry(mLoopParent, mParentLoop, loopScope, true)); - - // The second copy of the part of the loop condition is executed inside the loop. - TIntermSequence insertionsInLoop; - insertionsInLoop.push_back(createTempAssignment(node->deepCopy())); - mInsertions.push_back(NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, - empty, insertionsInLoop)); - } - return true; - } + insertStatementsInParentBlock(insertions); + + TIntermSymbol *ternaryResult = createTempSymbol(node->getType()); + queueReplacement(node, ternaryResult, OriginalNode::IS_DROPPED); - if (mInLoopExpression) - { - TIntermTyped *movedExpression = mParentLoop->getExpression(); - mReplacements.push_back(NodeUpdateEntry(mParentLoop, movedExpression, nullptr, false)); - TIntermAggregate *body = mParentLoop->getBody(); - TIntermSequence empty; - TIntermSequence insertions; - insertions.push_back(movedExpression); - mInsertions.push_back( - NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, empty, insertions)); - return true; - } return false; } diff --git a/chromium/third_party/angle/src/compiler/translator/UniformHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/UniformHLSL.cpp index 24d7760cb3a..3a85c60fc1b 100644 --- a/chromium/third_party/angle/src/compiler/translator/UniformHLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/UniformHLSL.cpp @@ -128,7 +128,7 @@ unsigned int UniformHLSL::assignSamplerInStructUniformRegister(const TType &type ASSERT(IsSampler(type.getBasicType())); unsigned int registerIndex = mSamplerRegister; mUniformRegisterMap[std::string(name.c_str())] = registerIndex; - unsigned int registerCount = type.isArray() ? type.getArraySize() : 1; + unsigned int registerCount = type.isArray() ? type.getArraySize() : 1u; mSamplerRegister += registerCount; if (outRegisterCount) { @@ -175,9 +175,9 @@ void UniformHLSL::outputHLSLSamplerUniformGroup( { out << "static const uint " << DecorateIfNeeded(uniform->getName()) << ArrayString(type) << " = {"; - for (int i = 0; i < type.getArraySize(); ++i) + for (unsigned int i = 0u; i < type.getArraySize(); ++i) { - if (i > 0) + if (i > 0u) out << ", "; out << (samplerArrayIndex + i); } @@ -281,7 +281,7 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out, { TVector<TIntermSymbol *> samplerSymbols; TMap<TIntermSymbol *, TString> symbolsToAPINames; - int arrayOfStructsSize = type.isArray() ? type.getArraySize() : 0; + unsigned int arrayOfStructsSize = type.isArray() ? type.getArraySize() : 0u; type.createSamplerSymbols("angle_" + name.getString(), name.getString(), arrayOfStructsSize, &samplerSymbols, &symbolsToAPINames); for (TIntermSymbol *sampler : samplerSymbols) diff --git a/chromium/third_party/angle/src/compiler/translator/UtilsHLSL.cpp b/chromium/third_party/angle/src/compiler/translator/UtilsHLSL.cpp index b3a065f19f8..221d5d9b56a 100644 --- a/chromium/third_party/angle/src/compiler/translator/UtilsHLSL.cpp +++ b/chromium/third_party/angle/src/compiler/translator/UtilsHLSL.cpp @@ -173,6 +173,8 @@ TString TextureTypeSuffix(const TBasicType type) return "Cube_int4_"; case EbtUSamplerCube: return "Cube_uint4_"; + case EbtSamplerExternalOES: + return "_External"; default: // All other types are identified by their group suffix return TextureGroupSuffix(type); diff --git a/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp b/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp index 29ca68d9cab..9f5f8f577d2 100644 --- a/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp @@ -60,7 +60,7 @@ int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const for (const auto &symbol : mOutputs) { const TType &type = symbol->getType(); - const size_t elementCount = static_cast<size_t>(type.isArray() ? type.getArraySize() : 1); + const size_t elementCount = static_cast<size_t>(type.isArray() ? type.getArraySize() : 1u); const size_t location = static_cast<size_t>(type.getLayoutQualifier().location); ASSERT(type.getLayoutQualifier().location != -1); diff --git a/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.cpp b/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.cpp index 9a4ed33632c..1ebdffd290d 100644 --- a/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.cpp +++ b/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.cpp @@ -59,11 +59,19 @@ bool ValidateSwitch::visitUnary(Visit, TIntermUnary *) { if (!mFirstCaseFound) mStatementBeforeCase = true; + mLastStatementWasCase = false; + return true; +} + +bool ValidateSwitch::visitTernary(Visit, TIntermTernary *) +{ + if (!mFirstCaseFound) + mStatementBeforeCase = true; mLastStatementWasCase = false; return true; } -bool ValidateSwitch::visitSelection(Visit visit, TIntermSelection *) +bool ValidateSwitch::visitIfElse(Visit visit, TIntermIfElse *) { if (visit == PreVisit) ++mControlFlowDepth; diff --git a/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.h b/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.h index ddbefc56197..fb6a614791e 100644 --- a/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.h +++ b/chromium/third_party/angle/src/compiler/translator/ValidateSwitch.h @@ -23,7 +23,8 @@ class ValidateSwitch : public TIntermTraverser void visitConstantUnion(TIntermConstantUnion *) override; bool visitBinary(Visit, TIntermBinary *) override; bool visitUnary(Visit, TIntermUnary *) override; - bool visitSelection(Visit visit, TIntermSelection *) override; + bool visitTernary(Visit, TIntermTernary *) override; + bool visitIfElse(Visit visit, TIntermIfElse *) override; bool visitSwitch(Visit, TIntermSwitch *) override; bool visitCase(Visit, TIntermCase *node) override; bool visitAggregate(Visit, TIntermAggregate *) override; diff --git a/chromium/third_party/angle/src/compiler/translator/VariableInfo.cpp b/chromium/third_party/angle/src/compiler/translator/VariableInfo.cpp index 611c1512d1f..7e1e5cd82a1 100644 --- a/chromium/third_party/angle/src/compiler/translator/VariableInfo.cpp +++ b/chromium/third_party/angle/src/compiler/translator/VariableInfo.cpp @@ -31,58 +31,6 @@ void ExpandUserDefinedVariable(const ShaderVariable &variable, const std::string &name, const std::string &mappedName, bool markStaticUse, - std::vector<ShaderVariable> *expanded); - -void ExpandVariable(const ShaderVariable &variable, - const std::string &name, - const std::string &mappedName, - bool markStaticUse, - std::vector<ShaderVariable> *expanded) -{ - if (variable.isStruct()) - { - if (variable.isArray()) - { - for (unsigned int elementIndex = 0; elementIndex < variable.elementCount(); - elementIndex++) - { - std::string lname = name + ::ArrayString(elementIndex); - std::string lmappedName = mappedName + ::ArrayString(elementIndex); - ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded); - } - } - else - { - ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded); - } - } - else - { - ShaderVariable expandedVar = variable; - - expandedVar.name = name; - expandedVar.mappedName = mappedName; - - // Mark all expanded fields as used if the parent is used - if (markStaticUse) - { - expandedVar.staticUse = true; - } - - if (expandedVar.isArray()) - { - expandedVar.name += "[0]"; - expandedVar.mappedName += "[0]"; - } - - expanded->push_back(expandedVar); - } -} - -void ExpandUserDefinedVariable(const ShaderVariable &variable, - const std::string &name, - const std::string &mappedName, - bool markStaticUse, std::vector<ShaderVariable> *expanded) { ASSERT(variable.isStruct()); @@ -122,7 +70,8 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs, std::vector<sh::Varying> *varyings, std::vector<sh::InterfaceBlock> *interfaceBlocks, ShHashFunction64 hashFunction, - const TSymbolTable &symbolTable) + const TSymbolTable &symbolTable, + const TExtensionBehavior &extensionBehavior) : TIntermTraverser(true, false, false), mAttribs(attribs), mOutputVariables(outputVariables), @@ -145,7 +94,8 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs, mSecondaryFragColorEXTAdded(false), mSecondaryFragDataEXTAdded(false), mHashFunction(hashFunction), - mSymbolTable(symbolTable) + mSymbolTable(symbolTable), + mExtensionBehavior(extensionBehavior) { } @@ -401,10 +351,17 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol) info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; - info.arraySize = static_cast<const TVariable *>( - mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100)) - ->getConstPointer() - ->getIConst(); + if (::IsExtensionEnabled(mExtensionBehavior, "GL_EXT_draw_buffers")) + { + info.arraySize = static_cast<const TVariable *>( + mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100)) + ->getConstPointer() + ->getIConst(); + } + else + { + info.arraySize = 1; + } info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; mOutputVariables->push_back(info); @@ -520,7 +477,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable, attribute.type = GLVariableType(type); attribute.precision = GLVariablePrecision(type); attribute.name = variable->getSymbol().c_str(); - attribute.arraySize = static_cast<unsigned int>(type.getArraySize()); + attribute.arraySize = type.getArraySize(); attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str(); attribute.location = variable->getType().getLayoutQualifier().location; @@ -540,7 +497,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable, attribute.type = GLVariableType(type); attribute.precision = GLVariablePrecision(type); attribute.name = variable->getSymbol().c_str(); - attribute.arraySize = static_cast<unsigned int>(type.getArraySize()); + attribute.arraySize = type.getArraySize(); attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str(); attribute.location = variable->getType().getLayoutQualifier().location; @@ -677,6 +634,52 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) return true; } +void ExpandVariable(const ShaderVariable &variable, + const std::string &name, + const std::string &mappedName, + bool markStaticUse, + std::vector<ShaderVariable> *expanded) +{ + if (variable.isStruct()) + { + if (variable.isArray()) + { + for (unsigned int elementIndex = 0; elementIndex < variable.elementCount(); + elementIndex++) + { + std::string lname = name + ::ArrayString(elementIndex); + std::string lmappedName = mappedName + ::ArrayString(elementIndex); + ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded); + } + } + else + { + ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded); + } + } + else + { + ShaderVariable expandedVar = variable; + + expandedVar.name = name; + expandedVar.mappedName = mappedName; + + // Mark all expanded fields as used if the parent is used + if (markStaticUse) + { + expandedVar.staticUse = true; + } + + if (expandedVar.isArray()) + { + expandedVar.name += "[0]"; + expandedVar.mappedName += "[0]"; + } + + expanded->push_back(expandedVar); + } +} + void ExpandUniforms(const std::vector<Uniform> &compact, std::vector<ShaderVariable> *expanded) { diff --git a/chromium/third_party/angle/src/compiler/translator/VariableInfo.h b/chromium/third_party/angle/src/compiler/translator/VariableInfo.h index e6d01758ec6..f79035d3842 100644 --- a/chromium/third_party/angle/src/compiler/translator/VariableInfo.h +++ b/chromium/third_party/angle/src/compiler/translator/VariableInfo.h @@ -9,6 +9,7 @@ #include <GLSLANG/ShaderLang.h> +#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/IntermNode.h" class TSymbolTable; @@ -26,7 +27,8 @@ class CollectVariables : public TIntermTraverser std::vector<Varying> *varyings, std::vector<InterfaceBlock> *interfaceBlocks, ShHashFunction64 hashFunction, - const TSymbolTable &symbolTable); + const TSymbolTable &symbolTable, + const TExtensionBehavior &extensionBehavior); void visitSymbol(TIntermSymbol *symbol) override; bool visitAggregate(Visit, TIntermAggregate *node) override; @@ -67,8 +69,15 @@ class CollectVariables : public TIntermTraverser ShHashFunction64 mHashFunction; const TSymbolTable &mSymbolTable; + const TExtensionBehavior &mExtensionBehavior; }; +void ExpandVariable(const ShaderVariable &variable, + const std::string &name, + const std::string &mappedName, + bool markStaticUse, + std::vector<ShaderVariable> *expanded); + // Expand struct uniforms to flattened lists of split variables void ExpandUniforms(const std::vector<Uniform> &compact, std::vector<ShaderVariable> *expanded); diff --git a/chromium/third_party/angle/src/compiler/translator/VariablePacker.cpp b/chromium/third_party/angle/src/compiler/translator/VariablePacker.cpp index e69052162a6..a981c8ae0b3 100644 --- a/chromium/third_party/angle/src/compiler/translator/VariablePacker.cpp +++ b/chromium/third_party/angle/src/compiler/translator/VariablePacker.cpp @@ -148,15 +148,21 @@ bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* de return true; } -template <typename VarT> -bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int maxVectors, - const std::vector<VarT> &in_variables) +bool VariablePacker::CheckVariablesWithinPackingLimits( + unsigned int maxVectors, + const std::vector<sh::ShaderVariable> &in_variables) { ASSERT(maxVectors > 0); maxRows_ = maxVectors; topNonFullRow_ = 0; bottomNonFullRow_ = maxRows_ - 1; - std::vector<VarT> variables(in_variables); + std::vector<sh::ShaderVariable> variables; + + for (const auto &variable : in_variables) + { + ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, + &variables); + } // Check whether each variable fits in the available vectors. for (size_t i = 0; i < variables.size(); i++) { @@ -261,9 +267,3 @@ bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int maxVectors, return true; } - -// Instantiate all possible variable packings -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::ShaderVariable> &); -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Attribute> &); -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Uniform> &); -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector<sh::Varying> &); diff --git a/chromium/third_party/angle/src/compiler/translator/VariablePacker.h b/chromium/third_party/angle/src/compiler/translator/VariablePacker.h index 9c80eea6187..5f38a0a98de 100644 --- a/chromium/third_party/angle/src/compiler/translator/VariablePacker.h +++ b/chromium/third_party/angle/src/compiler/translator/VariablePacker.h @@ -12,30 +12,29 @@ class VariablePacker { public: - // Returns true if the passed in variables pack in maxVectors following - // the packing rules from the GLSL 1.017 spec, Appendix A, section 7. - template <typename VarT> - bool CheckVariablesWithinPackingLimits(unsigned int maxVectors, - const std::vector<VarT> &in_variables); - - // Gets how many components in a row a data type takes. - static int GetNumComponentsPerRow(sh::GLenum type); - - // Gets how many rows a data type takes. - static int GetNumRows(sh::GLenum type); - - private: - static const int kNumColumns = 4; - static const unsigned kColumnMask = (1 << kNumColumns) - 1; - - unsigned makeColumnFlags(int column, int numComponentsPerRow); - void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow); - bool searchColumn(int column, int numRows, int* destRow, int* destSize); - - int topNonFullRow_; - int bottomNonFullRow_; - int maxRows_; - std::vector<unsigned> rows_; + // Returns true if the passed in variables pack in maxVectors following + // the packing rules from the GLSL 1.017 spec, Appendix A, section 7. + bool CheckVariablesWithinPackingLimits(unsigned int maxVectors, + const std::vector<sh::ShaderVariable> &in_variables); + + // Gets how many components in a row a data type takes. + static int GetNumComponentsPerRow(sh::GLenum type); + + // Gets how many rows a data type takes. + static int GetNumRows(sh::GLenum type); + + private: + static const int kNumColumns = 4; + static const unsigned kColumnMask = (1 << kNumColumns) - 1; + + unsigned makeColumnFlags(int column, int numComponentsPerRow); + void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow); + bool searchColumn(int column, int numRows, int *destRow, int *destSize); + + int topNonFullRow_; + int bottomNonFullRow_; + int maxRows_; + std::vector<unsigned> rows_; }; #endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.cpp deleted file mode 100644 index 4dee0dbd2e9..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraph.h" -#include "compiler/translator/depgraph/DependencyGraphBuilder.h" - -TDependencyGraph::TDependencyGraph(TIntermNode* intermNode) -{ - TDependencyGraphBuilder::build(intermNode, this); -} - -TDependencyGraph::~TDependencyGraph() -{ - for (TGraphNodeVector::const_iterator iter = mAllNodes.begin(); iter != mAllNodes.end(); ++iter) - { - TGraphNode* node = *iter; - delete node; - } -} - -TGraphArgument* TDependencyGraph::createArgument(TIntermAggregate* intermFunctionCall, - int argumentNumber) -{ - TGraphArgument* argument = new TGraphArgument(intermFunctionCall, argumentNumber); - mAllNodes.push_back(argument); - return argument; -} - -TGraphFunctionCall* TDependencyGraph::createFunctionCall(TIntermAggregate* intermFunctionCall) -{ - TGraphFunctionCall* functionCall = new TGraphFunctionCall(intermFunctionCall); - mAllNodes.push_back(functionCall); - if (functionCall->getIntermFunctionCall()->isUserDefined()) - mUserDefinedFunctionCalls.push_back(functionCall); - return functionCall; -} - -TGraphSymbol* TDependencyGraph::getOrCreateSymbol(TIntermSymbol* intermSymbol) -{ - TSymbolIdMap::const_iterator iter = mSymbolIdMap.find(intermSymbol->getId()); - - TGraphSymbol* symbol = NULL; - - if (iter != mSymbolIdMap.end()) { - TSymbolIdPair pair = *iter; - symbol = pair.second; - } else { - symbol = new TGraphSymbol(intermSymbol); - mAllNodes.push_back(symbol); - - TSymbolIdPair pair(intermSymbol->getId(), symbol); - mSymbolIdMap.insert(pair); - - // We save all sampler symbols in a collection, so we can start graph traversals from them quickly. - if (IsSampler(intermSymbol->getBasicType())) - mSamplerSymbols.push_back(symbol); - } - - return symbol; -} - -TGraphSelection* TDependencyGraph::createSelection(TIntermSelection* intermSelection) -{ - TGraphSelection* selection = new TGraphSelection(intermSelection); - mAllNodes.push_back(selection); - return selection; -} - -TGraphLoop* TDependencyGraph::createLoop(TIntermLoop* intermLoop) -{ - TGraphLoop* loop = new TGraphLoop(intermLoop); - mAllNodes.push_back(loop); - return loop; -} - -TGraphLogicalOp* TDependencyGraph::createLogicalOp(TIntermBinary* intermLogicalOp) -{ - TGraphLogicalOp* logicalOp = new TGraphLogicalOp(intermLogicalOp); - mAllNodes.push_back(logicalOp); - return logicalOp; -} - -const char* TGraphLogicalOp::getOpString() const -{ - const char* opString = NULL; - switch (getIntermLogicalOp()->getOp()) { - case EOpLogicalAnd: opString = "and"; break; - case EOpLogicalOr: opString = "or"; break; - default: opString = "unknown"; break; - } - return opString; -} diff --git a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.h b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.h deleted file mode 100644 index 2f7f7b9ab85..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraph.h +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_ -#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_ - -#include "compiler/translator/IntermNode.h" - -#include <set> -#include <stack> - -class TGraphNode; -class TGraphParentNode; -class TGraphArgument; -class TGraphFunctionCall; -class TGraphSymbol; -class TGraphSelection; -class TGraphLoop; -class TGraphLogicalOp; -class TDependencyGraphTraverser; -class TDependencyGraphOutput; - -typedef std::set<TGraphNode*> TGraphNodeSet; -typedef std::vector<TGraphNode*> TGraphNodeVector; -typedef std::vector<TGraphSymbol*> TGraphSymbolVector; -typedef std::vector<TGraphFunctionCall*> TFunctionCallVector; - -// -// Base class for all dependency graph nodes. -// -class TGraphNode { -public: - TGraphNode(TIntermNode* node) : intermNode(node) {} - virtual ~TGraphNode() {} - virtual void traverse(TDependencyGraphTraverser* graphTraverser); -protected: - TIntermNode* intermNode; -}; - -// -// Base class for dependency graph nodes that may have children. -// -class TGraphParentNode : public TGraphNode { -public: - TGraphParentNode(TIntermNode* node) : TGraphNode(node) {} - ~TGraphParentNode() override {} - void addDependentNode(TGraphNode* node) { if (node != this) mDependentNodes.insert(node); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; - -private: - TGraphNodeSet mDependentNodes; -}; - -// -// Handle function call arguments. -// -class TGraphArgument : public TGraphParentNode { -public: - TGraphArgument(TIntermAggregate* intermFunctionCall, int argumentNumber) - : TGraphParentNode(intermFunctionCall) - , mArgumentNumber(argumentNumber) {} - ~TGraphArgument() override {} - const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } - int getArgumentNumber() const { return mArgumentNumber; } - void traverse(TDependencyGraphTraverser *graphTraverser) override; - -private: - int mArgumentNumber; -}; - -// -// Handle function calls. -// -class TGraphFunctionCall : public TGraphParentNode { -public: - TGraphFunctionCall(TIntermAggregate* intermFunctionCall) - : TGraphParentNode(intermFunctionCall) {} - ~TGraphFunctionCall() override {} - const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle symbols. -// -class TGraphSymbol : public TGraphParentNode { -public: - TGraphSymbol(TIntermSymbol* intermSymbol) : TGraphParentNode(intermSymbol) {} - ~TGraphSymbol() override {} - const TIntermSymbol* getIntermSymbol() const { return intermNode->getAsSymbolNode(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle if statements and ternary operators. -// -class TGraphSelection : public TGraphNode { -public: - TGraphSelection(TIntermSelection* intermSelection) : TGraphNode(intermSelection) {} - ~TGraphSelection() override {} - const TIntermSelection* getIntermSelection() const { return intermNode->getAsSelectionNode(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle for, do-while, and while loops. -// -class TGraphLoop : public TGraphNode { -public: - TGraphLoop(TIntermLoop* intermLoop) : TGraphNode(intermLoop) {} - ~TGraphLoop() override {} - const TIntermLoop* getIntermLoop() const { return intermNode->getAsLoopNode(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle logical and, or. -// -class TGraphLogicalOp : public TGraphNode { -public: - TGraphLogicalOp(TIntermBinary* intermLogicalOp) : TGraphNode(intermLogicalOp) {} - ~TGraphLogicalOp() override {} - const TIntermBinary* getIntermLogicalOp() const { return intermNode->getAsBinaryNode(); } - const char* getOpString() const; - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// A dependency graph of symbols, function calls, conditions etc. -// -// This class provides an interface to the entry points of the dependency graph. -// -// Dependency graph nodes should be created by using one of the provided "create..." methods. -// This class (and nobody else) manages the memory of the created nodes. -// Nodes may not be removed after being added, so all created nodes will exist while the -// TDependencyGraph instance exists. -// -class TDependencyGraph { -public: - TDependencyGraph(TIntermNode* intermNode); - ~TDependencyGraph(); - const TGraphNodeVector &allNodes() const { return mAllNodes; } - const TGraphSymbolVector &samplerSymbols() const { return mSamplerSymbols; } - const TFunctionCallVector &userDefinedFunctionCalls() const - { - return mUserDefinedFunctionCalls; - } - - TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber); - TGraphFunctionCall* createFunctionCall(TIntermAggregate* intermFunctionCall); - TGraphSymbol* getOrCreateSymbol(TIntermSymbol* intermSymbol); - TGraphSelection* createSelection(TIntermSelection* intermSelection); - TGraphLoop* createLoop(TIntermLoop* intermLoop); - TGraphLogicalOp* createLogicalOp(TIntermBinary* intermLogicalOp); -private: - typedef TMap<int, TGraphSymbol*> TSymbolIdMap; - typedef std::pair<int, TGraphSymbol*> TSymbolIdPair; - - TGraphNodeVector mAllNodes; - TGraphSymbolVector mSamplerSymbols; - TFunctionCallVector mUserDefinedFunctionCalls; - TSymbolIdMap mSymbolIdMap; -}; - -// -// For traversing the dependency graph. Users should derive from this, -// put their traversal specific data in it, and then pass it to a -// traverse method. -// -// When using this, just fill in the methods for nodes you want visited. -// -class TDependencyGraphTraverser : angle::NonCopyable { -public: - TDependencyGraphTraverser() : mDepth(0) {} - virtual ~TDependencyGraphTraverser() {} - - virtual void visitSymbol(TGraphSymbol* symbol) {}; - virtual void visitArgument(TGraphArgument* selection) {}; - virtual void visitFunctionCall(TGraphFunctionCall* functionCall) {}; - virtual void visitSelection(TGraphSelection* selection) {}; - virtual void visitLoop(TGraphLoop* loop) {}; - virtual void visitLogicalOp(TGraphLogicalOp* logicalOp) {}; - - int getDepth() const { return mDepth; } - void incrementDepth() { ++mDepth; } - void decrementDepth() { --mDepth; } - - void clearVisited() { mVisited.clear(); } - void markVisited(TGraphNode* node) { mVisited.insert(node); } - bool isVisited(TGraphNode* node) const { return mVisited.find(node) != mVisited.end(); } -private: - int mDepth; - TGraphNodeSet mVisited; -}; - -#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp deleted file mode 100644 index 1aeb822d512..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp +++ /dev/null @@ -1,255 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraphBuilder.h" - -void TDependencyGraphBuilder::build(TIntermNode *node, TDependencyGraph *graph) -{ - TDependencyGraphBuilder builder(graph); - builder.build(node); -} - -bool TDependencyGraphBuilder::visitAggregate( - Visit visit, TIntermAggregate *intermAggregate) -{ - switch (intermAggregate->getOp()) - { - case EOpFunction: - visitFunctionDefinition(intermAggregate); - break; - case EOpFunctionCall: - visitFunctionCall(intermAggregate); - break; - default: - visitAggregateChildren(intermAggregate); - break; - } - return false; -} - -void TDependencyGraphBuilder::visitFunctionDefinition( - TIntermAggregate *intermAggregate) -{ - // Currently, we do not support user defined functions. - if (intermAggregate->getName() != "main(") - return; - - visitAggregateChildren(intermAggregate); -} - -// Takes an expression like "f(x)" and creates a dependency graph like -// "x -> argument 0 -> function call". -void TDependencyGraphBuilder::visitFunctionCall( - TIntermAggregate *intermFunctionCall) -{ - TGraphFunctionCall *functionCall = - mGraph->createFunctionCall(intermFunctionCall); - - // Run through the function call arguments. - int argumentNumber = 0; - TIntermSequence *intermArguments = intermFunctionCall->getSequence(); - for (TIntermSequence::const_iterator iter = intermArguments->begin(); - iter != intermArguments->end(); - ++iter, ++argumentNumber) - { - TNodeSetMaintainer nodeSetMaintainer(this); - - TIntermNode *intermArgument = *iter; - intermArgument->traverse(this); - - if (TParentNodeSet *argumentNodes = mNodeSets.getTopSet()) - { - TGraphArgument *argument = mGraph->createArgument( - intermFunctionCall, argumentNumber); - connectMultipleNodesToSingleNode(argumentNodes, argument); - argument->addDependentNode(functionCall); - } - } - - // Push the leftmost symbol of this function call into the current set of - // dependent symbols to represent the result of this function call. - // Thus, an expression like "y = f(x)" will yield a dependency graph like - // "x -> argument 0 -> function call -> y". - // This line essentially passes the function call node back up to an earlier - // visitAssignment call, which will create the connection "function call -> y". - mNodeSets.insertIntoTopSet(functionCall); -} - -void TDependencyGraphBuilder::visitAggregateChildren( - TIntermAggregate *intermAggregate) -{ - TIntermSequence *sequence = intermAggregate->getSequence(); - for (TIntermSequence::const_iterator iter = sequence->begin(); - iter != sequence->end(); ++iter) - { - TIntermNode *intermChild = *iter; - intermChild->traverse(this); - } -} - -void TDependencyGraphBuilder::visitSymbol(TIntermSymbol *intermSymbol) -{ - // Push this symbol into the set of dependent symbols for the current - // assignment or condition that we are traversing. - TGraphSymbol *symbol = mGraph->getOrCreateSymbol(intermSymbol); - mNodeSets.insertIntoTopSet(symbol); - - // If this symbol is the current leftmost symbol under an assignment, replace - // the previous leftmost symbol with this symbol. - if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree) - { - mLeftmostSymbols.pop(); - mLeftmostSymbols.push(symbol); - } -} - -bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary *intermBinary) -{ - TOperator op = intermBinary->getOp(); - if (op == EOpInitialize || intermBinary->isAssignment()) - visitAssignment(intermBinary); - else if (op == EOpLogicalAnd || op == EOpLogicalOr) - visitLogicalOp(intermBinary); - else - visitBinaryChildren(intermBinary); - - return false; -} - -void TDependencyGraphBuilder::visitAssignment(TIntermBinary *intermAssignment) -{ - TIntermTyped *intermLeft = intermAssignment->getLeft(); - if (!intermLeft) - return; - - TGraphSymbol *leftmostSymbol = NULL; - - { - TNodeSetMaintainer nodeSetMaintainer(this); - - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree); - intermLeft->traverse(this); - leftmostSymbol = mLeftmostSymbols.top(); - - // After traversing the left subtree of this assignment, we should - // have found a real leftmost symbol, and the leftmost symbol should - // not be a placeholder. - ASSERT(leftmostSymbol != &mLeftSubtree); - ASSERT(leftmostSymbol != &mRightSubtree); - } - - if (TIntermTyped *intermRight = intermAssignment->getRight()) - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); - intermRight->traverse(this); - } - - if (TParentNodeSet *assignmentNodes = mNodeSets.getTopSet()) - connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol); - } - - // Push the leftmost symbol of this assignment into the current set of dependent - // symbols to represent the result of this assignment. - // An expression like "a = (b = c)" will yield a dependency graph like - // "c -> b -> a". - // This line essentially passes the leftmost symbol of the nested assignment - // ("b" in this example) back up to the earlier visitAssignment call for the - // outer assignment, which will create the connection "b -> a". - mNodeSets.insertIntoTopSet(leftmostSymbol); -} - -void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary *intermLogicalOp) -{ - if (TIntermTyped *intermLeft = intermLogicalOp->getLeft()) - { - TNodeSetPropagatingMaintainer nodeSetMaintainer(this); - - intermLeft->traverse(this); - if (TParentNodeSet *leftNodes = mNodeSets.getTopSet()) - { - TGraphLogicalOp *logicalOp = mGraph->createLogicalOp(intermLogicalOp); - connectMultipleNodesToSingleNode(leftNodes, logicalOp); - } - } - - if (TIntermTyped *intermRight = intermLogicalOp->getRight()) - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); - intermRight->traverse(this); - } -} - -void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary *intermBinary) -{ - if (TIntermTyped *intermLeft = intermBinary->getLeft()) - intermLeft->traverse(this); - - if (TIntermTyped *intermRight = intermBinary->getRight()) - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); - intermRight->traverse(this); - } -} - -bool TDependencyGraphBuilder::visitSelection( - Visit visit, TIntermSelection *intermSelection) -{ - if (TIntermNode *intermCondition = intermSelection->getCondition()) - { - TNodeSetMaintainer nodeSetMaintainer(this); - - intermCondition->traverse(this); - if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet()) - { - TGraphSelection *selection = mGraph->createSelection(intermSelection); - connectMultipleNodesToSingleNode(conditionNodes, selection); - } - } - - if (TIntermNode *intermTrueBlock = intermSelection->getTrueBlock()) - intermTrueBlock->traverse(this); - - if (TIntermNode *intermFalseBlock = intermSelection->getFalseBlock()) - intermFalseBlock->traverse(this); - - return false; -} - -bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop *intermLoop) -{ - if (TIntermTyped *intermCondition = intermLoop->getCondition()) - { - TNodeSetMaintainer nodeSetMaintainer(this); - - intermCondition->traverse(this); - if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet()) - { - TGraphLoop *loop = mGraph->createLoop(intermLoop); - connectMultipleNodesToSingleNode(conditionNodes, loop); - } - } - - if (TIntermNode* intermBody = intermLoop->getBody()) - intermBody->traverse(this); - - if (TIntermTyped *intermExpression = intermLoop->getExpression()) - intermExpression->traverse(this); - - return false; -} - - -void TDependencyGraphBuilder::connectMultipleNodesToSingleNode( - TParentNodeSet *nodes, TGraphNode *node) const -{ - for (TParentNodeSet::const_iterator iter = nodes->begin(); - iter != nodes->end(); ++iter) - { - TGraphParentNode *currentNode = *iter; - currentNode->addDependentNode(node); - } -} diff --git a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h deleted file mode 100644 index c7b54f66b74..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_ -#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_ - -#include "compiler/translator/depgraph/DependencyGraph.h" - -// -// Creates a dependency graph of symbols, function calls, conditions etc. by -// traversing a intermediate tree. -// -class TDependencyGraphBuilder : public TIntermTraverser -{ - public: - static void build(TIntermNode *node, TDependencyGraph *graph); - - void visitSymbol(TIntermSymbol *) override; - bool visitBinary(Visit visit, TIntermBinary *) override; - bool visitSelection(Visit visit, TIntermSelection *) override; - bool visitAggregate(Visit visit, TIntermAggregate *) override; - bool visitLoop(Visit visit, TIntermLoop *) override; - - private: - typedef std::stack<TGraphSymbol *> TSymbolStack; - typedef std::set<TGraphParentNode *> TParentNodeSet; - - // - // For collecting the dependent nodes of assignments, conditions, etc. - // while traversing the intermediate tree. - // - // This data structure is stack of sets. Each set contains dependency graph - // parent nodes. - // - class TNodeSetStack - { - public: - TNodeSetStack() {}; - ~TNodeSetStack() { clear(); } - - // This should only be called after a pushSet. - // Returns NULL if the top set is empty. - TParentNodeSet *getTopSet() const - { - ASSERT(!mNodeSets.empty()); - TParentNodeSet *topSet = mNodeSets.top(); - return !topSet->empty() ? topSet : NULL; - } - - void pushSet() { mNodeSets.push(new TParentNodeSet()); } - void popSet() - { - ASSERT(!mNodeSets.empty()); - delete mNodeSets.top(); - mNodeSets.pop(); - } - - // Pops the top set and adds its contents to the new top set. - // This should only be called after a pushSet. - // If there is no set below the top set, the top set is just deleted. - void popSetIntoNext() - { - ASSERT(!mNodeSets.empty()); - TParentNodeSet *oldTopSet = mNodeSets.top(); - mNodeSets.pop(); - - if (!mNodeSets.empty()) - { - TParentNodeSet *newTopSet = mNodeSets.top(); - newTopSet->insert(oldTopSet->begin(), oldTopSet->end()); - } - - delete oldTopSet; - } - - // Does nothing if there is no top set. - // This can be called when there is no top set if we are visiting - // symbols that are not under an assignment or condition. - // We don't need to track those symbols. - void insertIntoTopSet(TGraphParentNode *node) - { - if (mNodeSets.empty()) - return; - - mNodeSets.top()->insert(node); - } - - void clear() - { - while (!mNodeSets.empty()) - popSet(); - } - - private: - typedef std::stack<TParentNodeSet *> TParentNodeSetStack; - - TParentNodeSetStack mNodeSets; - }; - - // - // An instance of this class pushes a new node set when instantiated. - // When the instance goes out of scope, it and pops the node set. - // - class TNodeSetMaintainer : angle::NonCopyable - { - public: - TNodeSetMaintainer(TDependencyGraphBuilder *factory) - : mSets(factory->mNodeSets) - { - mSets.pushSet(); - } - ~TNodeSetMaintainer() { mSets.popSet(); } - protected: - TNodeSetStack &mSets; - }; - - // - // An instance of this class pushes a new node set when instantiated. - // When the instance goes out of scope, it and pops the top node set and adds - // its contents to the new top node set. - // - class TNodeSetPropagatingMaintainer : angle::NonCopyable - { - public: - TNodeSetPropagatingMaintainer(TDependencyGraphBuilder *factory) - : mSets(factory->mNodeSets) - { - mSets.pushSet(); - } - ~TNodeSetPropagatingMaintainer() { mSets.popSetIntoNext(); } - protected: - TNodeSetStack &mSets; - }; - - // - // An instance of this class keeps track of the leftmost symbol while we're - // exploring an assignment. - // It will push the placeholder symbol kLeftSubtree when instantiated under a - // left subtree, and kRightSubtree under a right subtree. - // When it goes out of scope, it will pop the leftmost symbol at the top of the - // scope. - // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with - // a real symbol. - // kRightSubtree will never be replaced by a real symbol because we are tracking - // the leftmost symbol. - // - class TLeftmostSymbolMaintainer : angle::NonCopyable - { - public: - TLeftmostSymbolMaintainer( - TDependencyGraphBuilder *factory, TGraphSymbol &subtree) - : mLeftmostSymbols(factory->mLeftmostSymbols) - { - mNeedsPlaceholderSymbol = - mLeftmostSymbols.empty() || mLeftmostSymbols.top() != &subtree; - if (mNeedsPlaceholderSymbol) - mLeftmostSymbols.push(&subtree); - } - - ~TLeftmostSymbolMaintainer() - { - if (mNeedsPlaceholderSymbol) - mLeftmostSymbols.pop(); - } - - protected: - TSymbolStack& mLeftmostSymbols; - bool mNeedsPlaceholderSymbol; - }; - - TDependencyGraphBuilder(TDependencyGraph *graph) - : TIntermTraverser(true, false, false), - mLeftSubtree(NULL), - mRightSubtree(NULL), - mGraph(graph) {} - void build(TIntermNode *intermNode) { intermNode->traverse(this); } - - void connectMultipleNodesToSingleNode( - TParentNodeSet *nodes, TGraphNode *node) const; - - void visitAssignment(TIntermBinary *); - void visitLogicalOp(TIntermBinary *); - void visitBinaryChildren(TIntermBinary *); - void visitFunctionDefinition(TIntermAggregate *); - void visitFunctionCall(TIntermAggregate *intermFunctionCall); - void visitAggregateChildren(TIntermAggregate *); - - TGraphSymbol mLeftSubtree; - TGraphSymbol mRightSubtree; - - TDependencyGraph *mGraph; - TNodeSetStack mNodeSets; - TSymbolStack mLeftmostSymbols; -}; - -#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp deleted file mode 100644 index 32a2f30141d..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraphOutput.h" - -void TDependencyGraphOutput::outputIndentation() -{ - for (int i = 0; i < getDepth(); ++i) - mSink << " "; -} - -void TDependencyGraphOutput::visitArgument(TGraphArgument* parameter) -{ - outputIndentation(); - mSink << "argument " << parameter->getArgumentNumber() << " of call to " - << parameter->getIntermFunctionCall()->getName() << "\n"; -} - -void TDependencyGraphOutput::visitFunctionCall(TGraphFunctionCall* functionCall) -{ - outputIndentation(); - mSink << "function call " << functionCall->getIntermFunctionCall()->getName() << "\n"; -} - -void TDependencyGraphOutput::visitSymbol(TGraphSymbol* symbol) -{ - outputIndentation(); - mSink << symbol->getIntermSymbol()->getSymbol() << " (symbol id: " - << symbol->getIntermSymbol()->getId() << ")\n"; -} - -void TDependencyGraphOutput::visitSelection(TGraphSelection* selection) -{ - outputIndentation(); - mSink << "selection\n"; -} - -void TDependencyGraphOutput::visitLoop(TGraphLoop* loop) -{ - outputIndentation(); - mSink << "loop condition\n"; -} - -void TDependencyGraphOutput::visitLogicalOp(TGraphLogicalOp* logicalOp) -{ - outputIndentation(); - mSink << "logical " << logicalOp->getOpString() << "\n"; -} - -void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph& graph) -{ - mSink << "\n"; - - for (auto symbol : graph.allNodes()) - { - mSink << "--- Dependency graph spanning tree ---\n"; - clearVisited(); - symbol->traverse(this); - mSink << "\n"; - } -} diff --git a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h deleted file mode 100644 index b201e0a6712..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_ -#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_ - -#include "compiler/translator/depgraph/DependencyGraph.h" -#include "compiler/translator/InfoSink.h" - -class TDependencyGraphOutput : public TDependencyGraphTraverser -{ - public: - TDependencyGraphOutput(TInfoSinkBase& sink) : mSink(sink) {} - void visitSymbol(TGraphSymbol* symbol) override; - void visitArgument(TGraphArgument* parameter) override; - void visitFunctionCall(TGraphFunctionCall* functionCall) override; - void visitSelection(TGraphSelection* selection) override; - void visitLoop(TGraphLoop* loop) override; - void visitLogicalOp(TGraphLogicalOp* logicalOp) override; - - void outputAllSpanningTrees(TDependencyGraph& graph); - private: - void outputIndentation(); - - TInfoSinkBase& mSink; -}; - -#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp b/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp deleted file mode 100644 index 197fde97e26..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraph.h" - -// These methods do a breadth-first traversal through the graph and mark visited nodes. - -void TGraphNode::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->markVisited(this); -} - -void TGraphParentNode::traverse(TDependencyGraphTraverser* graphTraverser) -{ - TGraphNode::traverse(graphTraverser); - - graphTraverser->incrementDepth(); - - // Visit the parent node's children. - for (TGraphNodeSet::const_iterator iter = mDependentNodes.begin(); - iter != mDependentNodes.end(); - ++iter) - { - TGraphNode* node = *iter; - if (!graphTraverser->isVisited(node)) - node->traverse(graphTraverser); - } - - graphTraverser->decrementDepth(); -} - -void TGraphArgument::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitArgument(this); - TGraphParentNode::traverse(graphTraverser); -} - -void TGraphFunctionCall::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitFunctionCall(this); - TGraphParentNode::traverse(graphTraverser); -} - -void TGraphSymbol::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitSymbol(this); - TGraphParentNode::traverse(graphTraverser); -} - -void TGraphSelection::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitSelection(this); - TGraphNode::traverse(graphTraverser); -} - -void TGraphLoop::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitLoop(this); - TGraphNode::traverse(graphTraverser); -} - -void TGraphLogicalOp::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitLogicalOp(this); - TGraphNode::traverse(graphTraverser); -} diff --git a/chromium/third_party/angle/src/compiler/translator/glslang.l b/chromium/third_party/angle/src/compiler/translator/glslang.l index a4a296121dd..7fe28930275 100644 --- a/chromium/third_party/angle/src/compiler/translator/glslang.l +++ b/chromium/third_party/angle/src/compiler/translator/glslang.l @@ -392,7 +392,6 @@ O [0-7] <FIELDS>[ \t\v\f\r] {} <FIELDS>. { yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, ""); - yyextra->recover(); return 0; } @@ -437,7 +436,6 @@ int reserved_word(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); - yyextra->recover(); return 0; } @@ -487,7 +485,6 @@ int uint_constant(TParseContext *context) if (context->getShaderVersion() < 300) { context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); - context->recover(); return 0; } @@ -504,7 +501,6 @@ int floatsuffix_check(TParseContext* context) if (context->getShaderVersion() < 300) { context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); - context->recover(); return 0; } @@ -518,7 +514,6 @@ int floatsuffix_check(TParseContext* context) void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) { context->error(*lloc, reason, yyget_text(scanner)); - context->recover(); } int int_constant(TParseContext *context) { diff --git a/chromium/third_party/angle/src/compiler/translator/glslang.y b/chromium/third_party/angle/src/compiler/translator/glslang.y index f6903278b5b..ef2dcaa0a21 100644 --- a/chromium/third_party/angle/src/compiler/translator/glslang.y +++ b/chromium/third_party/angle/src/compiler/translator/glslang.y @@ -80,6 +80,7 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). TIntermCase* intermCase; }; union { + TTypeSpecifierNonArray typeSpecifierNonArray; TPublicType type; TPrecision precision; TLayoutQualifier layoutQualifier; @@ -88,6 +89,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). TParameter param; TField* field; TFieldList* fieldList; + TQualifierWrapperBase* qualifierWrapper; + TTypeQualifierBuilder* typeQualifierBuilder; }; } interm; } @@ -115,28 +118,42 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons #define VERTEX_ONLY(S, L) { \ if (context->getShaderType() != GL_VERTEX_SHADER) { \ context->error(L, " supported in vertex shaders only ", S); \ - context->recover(); \ } \ } #define FRAG_ONLY(S, L) { \ if (context->getShaderType() != GL_FRAGMENT_SHADER) { \ context->error(L, " supported in fragment shaders only ", S); \ - context->recover(); \ + } \ +} + +#define COMPUTE_ONLY(S, L) { \ + if (context->getShaderType() != GL_COMPUTE_SHADER) { \ + context->error(L, " supported in compute shaders only ", S); \ + } \ +} + +#define NON_COMPUTE_ONLY(S, L) { \ + if (context->getShaderType() != GL_VERTEX_SHADER && context->getShaderType() != GL_FRAGMENT_SHADER) { \ + context->error(L, " supported in vertex and fragment shaders only ", S); \ } \ } #define ES2_ONLY(S, L) { \ if (context->getShaderVersion() != 100) { \ context->error(L, " supported in GLSL ES 1.00 only ", S); \ - context->recover(); \ } \ } -#define ES3_ONLY(TOKEN, LINE, REASON) { \ - if (context->getShaderVersion() != 300) { \ - context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ - context->recover(); \ +#define ES3_OR_NEWER(TOKEN, LINE, REASON) { \ + if (context->getShaderVersion() < 300) { \ + context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN); \ + } \ +} + +#define ES3_1_ONLY(TOKEN, LINE, REASON) { \ + if (context->getShaderVersion() != 310) { \ + context->error(LINE, REASON " supported in GLSL ES 3.10 only ", TOKEN); \ } \ } %} @@ -191,13 +208,18 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %type <interm> single_declaration init_declarator_list %type <interm> parameter_declaration parameter_declarator parameter_type_specifier -%type <interm.qualifier> parameter_qualifier parameter_type_qualifier -%type <interm.layoutQualifier> layout_qualifier layout_qualifier_id_list layout_qualifier_id +%type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id + +%type <interm.type> fully_specified_type type_specifier %type <interm.precision> precision_qualifier -%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier -%type <interm.type> type_specifier_no_prec type_specifier_nonarray -%type <interm.type> struct_specifier +%type <interm.layoutQualifier> layout_qualifier +%type <interm.qualifier> storage_qualifier interpolation_qualifier +%type <interm.qualifierWrapper> single_type_qualifier invariant_qualifier +%type <interm.typeQualifierBuilder> type_qualifier + +%type <interm.typeSpecifierNonArray> type_specifier_nonarray struct_specifier +%type <interm.type> type_specifier_no_prec %type <interm.field> struct_declarator %type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list %type <interm.function> function_header function_declarator function_identifier @@ -276,8 +298,7 @@ postfix_expression integer_expression : expression { - if (context->integerErrorCheck($1, "[]")) - context->recover(); + context->checkIsScalarInteger($1, "[]"); $$ = $1; } ; @@ -299,7 +320,7 @@ function_call_or_method $$.nodePair.node2 = nullptr; } | postfix_expression DOT function_call_generic { - ES3_ONLY("", @3, "methods"); + ES3_OR_NEWER("", @3, "methods"); $$ = $3; $$.nodePair.node2 = $1; } @@ -330,7 +351,7 @@ function_call_header_with_parameters const TType *type = new TType($2->getType()); $1->addParameter(TConstParameter(type)); $$.function = $1; - $$.nodePair.node1 = context->intermediate.makeAggregate($2, @2); + $$.nodePair.node1 = TIntermediate::MakeAggregate($2, @2); } | function_call_header_with_parameters COMMA assignment_expression { const TType *type = new TType($3->getType()); @@ -351,20 +372,18 @@ function_call_header function_identifier : type_specifier_no_prec { if ($1.array) { - ES3_ONLY("[]", @1, "array constructor"); + ES3_OR_NEWER("[]", @1, "array constructor"); } $$ = context->addConstructorFunc($1); } | IDENTIFIER { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); + context->checkIsNotReserved(@1, *$1.string); const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction($1.string, type); $$ = function; } | FIELD_SELECTION { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); + context->checkIsNotReserved(@1, *$1.string); const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction($1.string, type); $$ = function; @@ -395,7 +414,7 @@ unary_operator | DASH { $$.op = EOpNegative; } | BANG { $$.op = EOpLogicalNot; } | TILDE { - ES3_ONLY("~", @$, "bit-wise operator"); + ES3_OR_NEWER("~", @$, "bit-wise operator"); $$.op = EOpBitwiseNot; } ; @@ -410,7 +429,7 @@ multiplicative_expression $$ = context->addBinaryMath(EOpDiv, $1, $3, @2); } | multiplicative_expression PERCENT unary_expression { - ES3_ONLY("%", @2, "integer modulus operator"); + ES3_OR_NEWER("%", @2, "integer modulus operator"); $$ = context->addBinaryMath(EOpIMod, $1, $3, @2); } ; @@ -428,11 +447,11 @@ additive_expression shift_expression : additive_expression { $$ = $1; } | shift_expression LEFT_OP additive_expression { - ES3_ONLY("<<", @2, "bit-wise operator"); + ES3_OR_NEWER("<<", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitShiftLeft, $1, $3, @2); } | shift_expression RIGHT_OP additive_expression { - ES3_ONLY(">>", @2, "bit-wise operator"); + ES3_OR_NEWER(">>", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitShiftRight, $1, $3, @2); } ; @@ -466,7 +485,7 @@ equality_expression and_expression : equality_expression { $$ = $1; } | and_expression AMPERSAND equality_expression { - ES3_ONLY("&", @2, "bit-wise operator"); + ES3_OR_NEWER("&", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitwiseAnd, $1, $3, @2); } ; @@ -474,7 +493,7 @@ and_expression exclusive_or_expression : and_expression { $$ = $1; } | exclusive_or_expression CARET and_expression { - ES3_ONLY("^", @2, "bit-wise operator"); + ES3_OR_NEWER("^", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitwiseXor, $1, $3, @2); } ; @@ -482,7 +501,7 @@ exclusive_or_expression inclusive_or_expression : exclusive_or_expression { $$ = $1; } | inclusive_or_expression VERTICAL_BAR exclusive_or_expression { - ES3_ONLY("|", @2, "bit-wise operator"); + ES3_OR_NEWER("|", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitwiseOr, $1, $3, @2); } ; @@ -518,8 +537,7 @@ conditional_expression assignment_expression : conditional_expression { $$ = $1; } | unary_expression assignment_operator assignment_expression { - if (context->lValueErrorCheck(@2, "assign", $1)) - context->recover(); + context->checkCanBeLValue(@2, "assign", $1); $$ = context->addAssign($2.op, $1, $3, @2); } ; @@ -529,29 +547,29 @@ assignment_operator | MUL_ASSIGN { $$.op = EOpMulAssign; } | DIV_ASSIGN { $$.op = EOpDivAssign; } | MOD_ASSIGN { - ES3_ONLY("%=", @$, "integer modulus operator"); + ES3_OR_NEWER("%=", @$, "integer modulus operator"); $$.op = EOpIModAssign; } | ADD_ASSIGN { $$.op = EOpAddAssign; } | SUB_ASSIGN { $$.op = EOpSubAssign; } | LEFT_ASSIGN { - ES3_ONLY("<<=", @$, "bit-wise operator"); + ES3_OR_NEWER("<<=", @$, "bit-wise operator"); $$.op = EOpBitShiftLeftAssign; } | RIGHT_ASSIGN { - ES3_ONLY(">>=", @$, "bit-wise operator"); + ES3_OR_NEWER(">>=", @$, "bit-wise operator"); $$.op = EOpBitShiftRightAssign; } | AND_ASSIGN { - ES3_ONLY("&=", @$, "bit-wise operator"); + ES3_OR_NEWER("&=", @$, "bit-wise operator"); $$.op = EOpBitwiseAndAssign; } | XOR_ASSIGN { - ES3_ONLY("^=", @$, "bit-wise operator"); + ES3_OR_NEWER("^=", @$, "bit-wise operator"); $$.op = EOpBitwiseXorAssign; } | OR_ASSIGN { - ES3_ONLY("|=", @$, "bit-wise operator"); + ES3_OR_NEWER("|=", @$, "bit-wise operator"); $$.op = EOpBitwiseOrAssign; } ; @@ -567,16 +585,14 @@ expression constant_expression : conditional_expression { - if (context->constErrorCheck($1)) - context->recover(); + context->checkIsConst($1); $$ = $1; } ; enter_struct : IDENTIFIER LEFT_BRACE { - if (context->enterStructDeclaration(@1, *$1.string)) - context->recover(); + context->enterStructDeclaration(@1, *$1.string); $$ = $1; } ; @@ -594,35 +610,38 @@ declaration | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { context->error(@1, "precision is not supported in fragment shader", "highp"); - context->recover(); } if (!context->symbolTable.setDefaultPrecision( $3, $2 )) { - context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type)); - context->recover(); + context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.getBasicType())); } $$ = 0; } | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { - ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); - $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @$, NULL, @$); + ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); + $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, NULL, @$, NULL, @$); } | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON { - ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); - $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @$); + ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); + $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, NULL, @$); } | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON { - ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); - $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6); + ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); + $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, $7, @6); } | type_qualifier SEMICOLON { - context->parseGlobalLayoutQualifier($1); + context->parseGlobalLayoutQualifier(*$1); $$ = 0; } + | type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant + { + $$ = context->parseInvariantDeclaration(*$1, @2, $2.string, $2.symbol); + } ; function_prototype : function_declarator RIGHT_PAREN { $$.function = context->parseFunctionDeclarator(@2, $1); + context->exitFunctionDeclaration(); } ; @@ -655,7 +674,6 @@ function_header_with_parameters // This parameter > first is void // context->error(@2, "cannot be an argument type except for '(void)'", "void"); - context->recover(); delete $3.param.type; } else { // Add the parameter @@ -670,32 +688,28 @@ function_header $$ = context->parseFunctionHeader($1, $2.string, @2); context->symbolTable.push(); + context->enterFunctionDeclaration(); } ; parameter_declarator // Type + name : type_specifier identifier { - if ($1.type == EbtVoid) { + if ($1.getBasicType() == EbtVoid) { context->error(@2, "illegal use of type 'void'", $2.string->c_str()); - context->recover(); } - if (context->reservedErrorCheck(@2, *$2.string)) - context->recover(); + context->checkIsNotReserved(@2, *$2.string); TParameter param = {$2.string, new TType($1)}; $$.param = param; } | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { // Check that we can make an array out of this type - if (context->arrayTypeErrorCheck(@3, $1)) - context->recover(); + context->checkIsValidTypeForArray(@3, $1); - if (context->reservedErrorCheck(@2, *$2.string)) - context->recover(); + context->checkIsNotReserved(@2, *$2.string); + + unsigned int size = context->checkIsValidArraySize(@3, $4); - int size; - if (context->arraySizeErrorCheck(@3, $4, size)) - context->recover(); $1.setArraySize(size); TType* type = new TType($1); @@ -713,47 +727,21 @@ parameter_declaration // // Type + name // - : parameter_type_qualifier parameter_qualifier parameter_declarator { - $$ = $3; - if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) - context->recover(); - } - | parameter_qualifier parameter_declarator { + : type_qualifier parameter_declarator { $$ = $2; - if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) - context->recover(); - if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) - context->recover(); + context->checkIsParameterQualifierValid(@2, *$1, $2.param.type); } - // - // Only type - // - | parameter_type_qualifier parameter_qualifier parameter_type_specifier { - $$ = $3; - if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) - context->recover(); + | parameter_declarator { + $$ = $1; + $$.param.type->setQualifier(EvqIn); } - | parameter_qualifier parameter_type_specifier { + | type_qualifier parameter_type_specifier { $$ = $2; - if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) - context->recover(); - if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) - context->recover(); - } - ; - -parameter_qualifier - : /* empty */ { - $$ = EvqIn; - } - | IN_QUAL { - $$ = EvqIn; - } - | OUT_QUAL { - $$ = EvqOut; + context->checkIsParameterQualifierValid(@2, *$1, $2.param.type); } - | INOUT_QUAL { - $$ = EvqInOut; + | parameter_type_specifier { + $$ = $1; + $$.param.type->setQualifier(EvqIn); } ; @@ -777,12 +765,12 @@ init_declarator_list $$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); } | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("[]", @3, "implicitly sized array"); + ES3_OR_NEWER("[]", @3, "implicitly sized array"); $$ = $1; $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, nullptr, @6, $7); } | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("=", @7, "first-class arrays (array initializer)"); + ES3_OR_NEWER("=", @7, "first-class arrays (array initializer)"); $$ = $1; $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5, @7, $8); } @@ -806,12 +794,12 @@ single_declaration $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); } | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("[]", @3, "implicitly sized array"); + ES3_OR_NEWER("[]", @3, "implicitly sized array"); $$.type = $1; $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6); } | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("=", @6, "first-class arrays (array initializer)"); + ES3_OR_NEWER("=", @6, "first-class arrays (array initializer)"); $$.type = $1; $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7); } @@ -819,10 +807,6 @@ single_declaration $$.type = $1; $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); } - | INVARIANT IDENTIFIER { - // $$.type is not used in invariant declarations. - $$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol); - } ; fully_specified_type @@ -830,131 +814,140 @@ fully_specified_type $$ = $1; if ($1.array) { - ES3_ONLY("[]", @1, "first-class-array"); + ES3_OR_NEWER("[]", @1, "first-class-array"); if (context->getShaderVersion() != 300) { $1.clearArrayness(); } } } - | type_qualifier type_specifier { - $$ = context->addFullySpecifiedType($1.qualifier, $1.invariant, $1.layoutQualifier, $2); + | type_qualifier type_specifier { + $$ = context->addFullySpecifiedType(*$1, $2); } ; interpolation_qualifier : SMOOTH { - $$.qualifier = EvqSmooth; + $$ = EvqSmooth; } | FLAT { - $$.qualifier = EvqFlat; - } - ; - -parameter_type_qualifier - : CONST_QUAL { - $$ = EvqConst; + $$ = EvqFlat; } ; type_qualifier - : ATTRIBUTE { - VERTEX_ONLY("attribute", @1); - ES2_ONLY("attribute", @1); - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute")) - context->recover(); - $$.setBasic(EbtVoid, EvqAttribute, @1); + : single_type_qualifier { + $$ = context->createTypeQualifierBuilder(@1); + $$->appendQualifier($1); } - | VARYING { - ES2_ONLY("varying", @1); - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying")) - context->recover(); - if (context->getShaderType() == GL_VERTEX_SHADER) - $$.setBasic(EbtVoid, EvqVaryingOut, @1); - else - $$.setBasic(EbtVoid, EvqVaryingIn, @1); + | type_qualifier single_type_qualifier { + $$ = $1; + $$->appendQualifier($2); } - | INVARIANT VARYING { - ES2_ONLY("varying", @1); - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) - context->recover(); - if (context->getShaderType() == GL_VERTEX_SHADER) - $$.setBasic(EbtVoid, EvqVaryingOut, @1); - else - $$.setBasic(EbtVoid, EvqVaryingIn, @1); - $$.invariant = true; + ; + +invariant_qualifier + : INVARIANT { + // empty } - | storage_qualifier { - if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) + ; + +single_type_qualifier + : storage_qualifier { + if (!context->declaringFunction() && $1 != EvqConst && !context->symbolTable.atGlobalLevel()) { - context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier)); - context->recover(); + context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1)); } - $$.setBasic(EbtVoid, $1.qualifier, @1); - } - | interpolation_qualifier storage_qualifier { - $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier); - } - | interpolation_qualifier { - context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier)); - context->recover(); - - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtVoid, qual, @1); + $$ = new TStorageQualifierWrapper($1, @1); } | layout_qualifier { - $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.layoutQualifier = $1; + context->checkIsAtGlobalLevel(@1, "layout"); + $$ = new TLayoutQualifierWrapper($1, @1); } - | layout_qualifier storage_qualifier { - $$.setBasic(EbtVoid, $2.qualifier, @2); - $$.layoutQualifier = $1; + | precision_qualifier { + $$ = new TPrecisionQualifierWrapper($1, @1); } - | INVARIANT storage_qualifier { - context->es3InvariantErrorCheck($2.qualifier, @1); - $$.setBasic(EbtVoid, $2.qualifier, @2); - $$.invariant = true; + | interpolation_qualifier { + $$ = new TInterpolationQualifierWrapper($1, @1); } - | INVARIANT interpolation_qualifier storage_qualifier { - context->es3InvariantErrorCheck($3.qualifier, @1); - $$ = context->joinInterpolationQualifiers(@2, $2.qualifier, @3, $3.qualifier); - $$.invariant = true; + | invariant_qualifier { + context->checkIsAtGlobalLevel(@1, "invariant"); + $$ = new TInvariantQualifierWrapper(@1); } ; + storage_qualifier - : CONST_QUAL { - $$.qualifier = EvqConst; + : + ATTRIBUTE { + VERTEX_ONLY("attribute", @1); + ES2_ONLY("attribute", @1); + context->checkIsAtGlobalLevel(@1, "attribute"); + $$ = EvqAttribute; + } + | VARYING { + ES2_ONLY("varying", @1); + context->checkIsAtGlobalLevel(@1, "varying"); + if (context->getShaderType() == GL_VERTEX_SHADER) + $$ = EvqVaryingOut; + else + $$ = EvqVaryingIn; + } + | CONST_QUAL { + $$ = EvqConst; } | IN_QUAL { - ES3_ONLY("in", @1, "storage qualifier"); - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + if (context->declaringFunction()) + { + $$ = EvqIn; + } + else if (context->getShaderType() == GL_FRAGMENT_SHADER) + { + ES3_OR_NEWER("in", @1, "storage qualifier"); + $$ = EvqFragmentIn; + } + else if (context->getShaderType() == GL_VERTEX_SHADER) + { + ES3_OR_NEWER("in", @1, "storage qualifier"); + $$ = EvqVertexIn; + } + else + { + $$ = EvqComputeIn; + } } | OUT_QUAL { - ES3_ONLY("out", @1, "storage qualifier"); - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; - } - | CENTROID IN_QUAL { - ES3_ONLY("centroid in", @1, "storage qualifier"); - if (context->getShaderType() == GL_VERTEX_SHADER) + if (context->declaringFunction()) + { + $$ = EvqOut; + } + else { - context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); - context->recover(); + ES3_OR_NEWER("out", @1, "storage qualifier"); + NON_COMPUTE_ONLY("out", @1); + if (context->getShaderType() == GL_FRAGMENT_SHADER) + { + $$ = EvqFragmentOut; + } + else + { + $$ = EvqVertexOut; + } } - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; } - | CENTROID OUT_QUAL { - ES3_ONLY("centroid out", @1, "storage qualifier"); - if (context->getShaderType() == GL_FRAGMENT_SHADER) + | INOUT_QUAL { + if (!context->declaringFunction()) { - context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); - context->recover(); + context->error(@1, "invalid inout qualifier", "'inout' can be only used with function parameters"); } - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + $$ = EvqInOut; + } + | CENTROID { + ES3_OR_NEWER("centroid", @1, "storage qualifier"); + $$ = EvqCentroid; } | UNIFORM { - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform")) - context->recover(); - $$.qualifier = EvqUniform; + context->checkIsAtGlobalLevel(@1, "uniform"); + $$ = EvqUniform; } ; @@ -963,19 +956,7 @@ type_specifier $$ = $1; if ($$.precision == EbpUndefined) { - $$.precision = context->symbolTable.getDefaultPrecision($1.type); - if (context->precisionErrorCheck(@1, $$.precision, $1.type)) { - context->recover(); - } - } - } - | precision_qualifier type_specifier_no_prec { - $$ = $2; - $$.precision = $1; - - if (!SupportsPrecision($2.type)) { - context->error(@1, "illegal type for precision qualifier", getBasicString($2.type)); - context->recover(); + $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType()); } } ; @@ -994,7 +975,7 @@ precision_qualifier layout_qualifier : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { - ES3_ONLY("layout", @1, "qualifier"); + ES3_OR_NEWER("layout", @1, "qualifier"); $$ = $3; } ; @@ -1004,7 +985,7 @@ layout_qualifier_id_list $$ = $1; } | layout_qualifier_id_list COMMA layout_qualifier_id { - $$ = context->joinLayoutQualifiers($1, $3); + $$ = context->joinLayoutQualifiers($1, $3, @3); } ; @@ -1013,31 +994,27 @@ layout_qualifier_id $$ = context->parseLayoutQualifier(*$1.string, @1); } | IDENTIFIER EQUAL INTCONSTANT { - $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3); } | IDENTIFIER EQUAL UINTCONSTANT { - $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3); } ; type_specifier_no_prec : type_specifier_nonarray { - $$ = $1; + $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); } | type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET { - ES3_ONLY("[]", @2, "implicitly sized array"); - $$ = $1; + ES3_OR_NEWER("[]", @2, "implicitly sized array"); + $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); $$.setArraySize(0); } | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET { - $$ = $1; - - if (context->arrayTypeErrorCheck(@2, $1)) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck(@2, $3, size)) - context->recover(); + $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); + if (context->checkIsValidTypeForArray(@2, $$)) + { + unsigned int size = context->checkIsValidArraySize(@2, $3); $$.setArraySize(size); } } @@ -1045,210 +1022,164 @@ type_specifier_no_prec type_specifier_nonarray : VOID_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtVoid, qual, @1); + $$.initialize(EbtVoid, @1); } | FLOAT_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); } | INT_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); } | UINT_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); } | BOOL_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); } | VEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setAggregate(2); } | VEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setAggregate(3); } | VEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setAggregate(4); } | BVEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); $$.setAggregate(2); } | BVEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); $$.setAggregate(3); } | BVEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); $$.setAggregate(4); } | IVEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); $$.setAggregate(2); } | IVEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); $$.setAggregate(3); } | IVEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); $$.setAggregate(4); } | UVEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); $$.setAggregate(2); } | UVEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); $$.setAggregate(3); } | UVEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); $$.setAggregate(4); } | MATRIX2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(2, 2); } | MATRIX3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(3, 3); } | MATRIX4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(4, 4); } | MATRIX2x3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(2, 3); } | MATRIX3x2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(3, 2); } | MATRIX2x4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(2, 4); } | MATRIX4x2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(4, 2); } | MATRIX3x4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(3, 4); } | MATRIX4x3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(4, 3); } | SAMPLER2D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2D, qual, @1); + $$.initialize(EbtSampler2D, @1); } | SAMPLER3D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler3D, qual, @1); + $$.initialize(EbtSampler3D, @1); } | SAMPLERCUBE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSamplerCube, qual, @1); + $$.initialize(EbtSamplerCube, @1); } | SAMPLER2DARRAY { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DArray, qual, @1); + $$.initialize(EbtSampler2DArray, @1); } | ISAMPLER2D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISampler2D, qual, @1); + $$.initialize(EbtISampler2D, @1); } | ISAMPLER3D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISampler3D, qual, @1); + $$.initialize(EbtISampler3D, @1); } | ISAMPLERCUBE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISamplerCube, qual, @1); + $$.initialize(EbtISamplerCube, @1); } | ISAMPLER2DARRAY { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISampler2DArray, qual, @1); + $$.initialize(EbtISampler2DArray, @1); } | USAMPLER2D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSampler2D, qual, @1); + $$.initialize(EbtUSampler2D, @1); } | USAMPLER3D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSampler3D, qual, @1); + $$.initialize(EbtUSampler3D, @1); } | USAMPLERCUBE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSamplerCube, qual, @1); + $$.initialize(EbtUSamplerCube, @1); } | USAMPLER2DARRAY { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSampler2DArray, qual, @1); + $$.initialize(EbtUSampler2DArray, @1); } | SAMPLER2DSHADOW { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DShadow, qual, @1); + $$.initialize(EbtSampler2DShadow, @1); } | SAMPLERCUBESHADOW { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSamplerCubeShadow, qual, @1); + $$.initialize(EbtSamplerCubeShadow, @1); } | SAMPLER2DARRAYSHADOW { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DArrayShadow, qual, @1); + $$.initialize(EbtSampler2DArrayShadow, @1); } | SAMPLER_EXTERNAL_OES { if (!context->supportsExtension("GL_OES_EGL_image_external") && !context->supportsExtension("GL_NV_EGL_stream_consumer_external")) { context->error(@1, "unsupported type", "samplerExternalOES"); - context->recover(); } - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSamplerExternalOES, qual, @1); + $$.initialize(EbtSamplerExternalOES, @1); } | SAMPLER2DRECT { if (!context->supportsExtension("GL_ARB_texture_rectangle")) { context->error(@1, "unsupported type", "sampler2DRect"); - context->recover(); } - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DRect, qual, @1); + $$.initialize(EbtSampler2DRect, @1); } | struct_specifier { $$ = $1; - $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; } | TYPE_NAME { // @@ -1256,17 +1187,16 @@ type_specifier_nonarray // type. // TType& structure = static_cast<TVariable*>($1.symbol)->getType(); - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtStruct, qual, @1); + $$.initialize(EbtStruct, @1); $$.userDef = &structure; } ; struct_specifier - : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { + : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE { $$ = context->addStructure(@1, @2, $2.string, $5); } - | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { + | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE { $$ = context->addStructure(@1, @$, NewPoolTString(""), $4); } ; @@ -1282,7 +1212,6 @@ struct_declaration_list for (size_t j = 0; j < $$->size(); ++j) { if ((*$$)[j]->name() == field->name()) { context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str()); - context->recover(); } } $$->push_back(field); @@ -1296,9 +1225,7 @@ struct_declaration } | type_qualifier type_specifier struct_declarator_list SEMICOLON { // ES3 Only, but errors should be handled elsewhere - $2.qualifier = $1.qualifier; - $2.layoutQualifier = $1.layoutQualifier; - $$ = context->addStructDeclaratorList($2, $3); + $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3); } ; @@ -1314,20 +1241,16 @@ struct_declarator_list struct_declarator : identifier { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); + context->checkIsNotReserved(@1, *$1.string); TType* type = new TType(EbtVoid, EbpUndefined); $$ = new TField(type, $1.string, @1); } | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); + context->checkIsNotReserved(@1, *$1.string); TType* type = new TType(EbtVoid, EbpUndefined); - int size; - if (context->arraySizeErrorCheck(@3, $3, size)) - context->recover(); + unsigned int size = context->checkIsValidArraySize(@3, $3); type->setArraySize(size); $$ = new TField(type, $1.string, @1); @@ -1396,7 +1319,7 @@ compound_statement_no_new_scope statement_list : statement { - $$ = context->intermediate.makeAggregate($1, @$); + $$ = TIntermediate::MakeAggregate($1, @$); } | statement_list statement { $$ = context->intermediate.growAggregate($1, $2, @$); @@ -1410,9 +1333,8 @@ expression_statement selection_statement : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { - if (context->boolErrorCheck(@1, $3)) - context->recover(); - $$ = context->intermediate.addSelection($3, $5, @1); + context->checkIsScalarBool(@1, $3); + $$ = context->intermediate.addIfElse($3, $5, @1); } ; @@ -1447,18 +1369,15 @@ condition // In 1996 c++ draft, conditions can include single declarations : expression { $$ = $1; - if (context->boolErrorCheck($1->getLine(), $1)) - context->recover(); + context->checkIsScalarBool($1->getLine(), $1); } | fully_specified_type identifier EQUAL initializer { TIntermNode *intermNode; - if (context->boolErrorCheck(@2, $1)) - context->recover(); + context->checkIsScalarBool(@2, $1); if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode)) $$ = $4; else { - context->recover(); $$ = 0; } } @@ -1471,8 +1390,7 @@ iteration_statement context->decrLoopNestingLevel(); } | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { - if (context->boolErrorCheck(@8, $6)) - context->recover(); + context->checkIsScalarBool(@8, $6); $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); context->decrLoopNestingLevel(); diff --git a/chromium/third_party/angle/src/compiler/translator/glslang_lex.cpp b/chromium/third_party/angle/src/compiler/translator/glslang_lex.cpp index ff6c2d6b1cc..8ad7b1464d4 100644 --- a/chromium/third_party/angle/src/compiler/translator/glslang_lex.cpp +++ b/chromium/third_party/angle/src/compiler/translator/glslang_lex.cpp @@ -2075,7 +2075,6 @@ case 237: YY_RULE_SETUP { yyextra->error(*yylloc, "Illegal character at fieldname start", yytext, ""); - yyextra->recover(); return 0; } YY_BREAK @@ -3275,7 +3274,6 @@ int reserved_word(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); - yyextra->recover(); return 0; } @@ -3325,7 +3323,6 @@ int uint_constant(TParseContext *context) if (context->getShaderVersion() < 300) { context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); - context->recover(); return 0; } @@ -3342,7 +3339,6 @@ int floatsuffix_check(TParseContext* context) if (context->getShaderVersion() < 300) { context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); - context->recover(); return 0; } @@ -3356,7 +3352,6 @@ int floatsuffix_check(TParseContext* context) void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) { context->error(*lloc, reason, yyget_text(scanner)); - context->recover(); } int int_constant(TParseContext *context) { diff --git a/chromium/third_party/angle/src/compiler/translator/glslang_tab.cpp b/chromium/third_party/angle/src/compiler/translator/glslang_tab.cpp index a2784d3685b..2d3f170e7de 100644 --- a/chromium/third_party/angle/src/compiler/translator/glslang_tab.cpp +++ b/chromium/third_party/angle/src/compiler/translator/glslang_tab.cpp @@ -295,6 +295,7 @@ union YYSTYPE TIntermCase* intermCase; }; union { + TTypeSpecifierNonArray typeSpecifierNonArray; TPublicType type; TPrecision precision; TLayoutQualifier layoutQualifier; @@ -303,6 +304,8 @@ union YYSTYPE TParameter param; TField* field; TFieldList* fieldList; + TQualifierWrapperBase* qualifierWrapper; + TTypeQualifierBuilder* typeQualifierBuilder; }; } interm; @@ -359,28 +362,42 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons #define VERTEX_ONLY(S, L) { \ if (context->getShaderType() != GL_VERTEX_SHADER) { \ context->error(L, " supported in vertex shaders only ", S); \ - context->recover(); \ } \ } #define FRAG_ONLY(S, L) { \ if (context->getShaderType() != GL_FRAGMENT_SHADER) { \ context->error(L, " supported in fragment shaders only ", S); \ - context->recover(); \ + } \ +} + +#define COMPUTE_ONLY(S, L) { \ + if (context->getShaderType() != GL_COMPUTE_SHADER) { \ + context->error(L, " supported in compute shaders only ", S); \ + } \ +} + +#define NON_COMPUTE_ONLY(S, L) { \ + if (context->getShaderType() != GL_VERTEX_SHADER && context->getShaderType() != GL_FRAGMENT_SHADER) { \ + context->error(L, " supported in vertex and fragment shaders only ", S); \ } \ } #define ES2_ONLY(S, L) { \ if (context->getShaderVersion() != 100) { \ context->error(L, " supported in GLSL ES 1.00 only ", S); \ - context->recover(); \ } \ } -#define ES3_ONLY(TOKEN, LINE, REASON) { \ - if (context->getShaderVersion() != 300) { \ - context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ - context->recover(); \ +#define ES3_OR_NEWER(TOKEN, LINE, REASON) { \ + if (context->getShaderVersion() < 300) { \ + context->error(LINE, REASON " supported in GLSL ES 3.00 and above only ", TOKEN); \ + } \ +} + +#define ES3_1_ONLY(TOKEN, LINE, REASON) { \ + if (context->getShaderVersion() != 310) { \ + context->error(LINE, REASON " supported in GLSL ES 3.10 only ", TOKEN); \ } \ } @@ -626,18 +643,18 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 116 +#define YYFINAL 109 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 2516 +#define YYLAST 2432 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 128 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 94 /* YYNRULES -- Number of rules. */ -#define YYNRULES 275 +#define YYNRULES 269 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 417 +#define YYNSTATES 405 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ @@ -696,34 +713,33 @@ static const yytype_uint8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 214, 214, 215, 218, 228, 231, 236, 241, 246, - 251, 257, 260, 263, 266, 269, 272, 278, 286, 297, - 301, 309, 312, 318, 322, 329, 335, 344, 352, 358, - 365, 375, 378, 381, 384, 394, 395, 396, 397, 405, - 406, 409, 412, 419, 420, 423, 429, 430, 434, 441, - 442, 445, 448, 451, 457, 458, 461, 467, 468, 475, - 476, 483, 484, 491, 492, 498, 499, 505, 506, 512, - 513, 519, 520, 528, 529, 530, 531, 535, 536, 537, - 541, 545, 549, 553, 560, 563, 569, 577, 585, 588, - 594, 605, 609, 613, 617, 624, 630, 633, 640, 648, - 669, 678, 688, 716, 721, 731, 736, 746, 749, 752, - 755, 761, 768, 771, 775, 779, 784, 789, 796, 800, - 804, 808, 813, 818, 822, 829, 839, 845, 848, 854, - 860, 867, 876, 886, 894, 897, 904, 908, 912, 917, - 925, 928, 932, 936, 945, 954, 962, 972, 984, 987, - 990, 996, 1003, 1006, 1012, 1015, 1018, 1024, 1027, 1032, - 1047, 1051, 1055, 1059, 1063, 1067, 1072, 1077, 1082, 1087, - 1092, 1097, 1102, 1107, 1112, 1117, 1122, 1127, 1132, 1137, - 1142, 1147, 1152, 1157, 1162, 1167, 1172, 1176, 1180, 1184, - 1188, 1192, 1196, 1200, 1204, 1208, 1212, 1216, 1220, 1224, - 1228, 1232, 1241, 1249, 1253, 1266, 1266, 1269, 1269, 1275, - 1278, 1294, 1297, 1306, 1310, 1316, 1323, 1338, 1342, 1346, - 1347, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1363, 1364, - 1364, 1364, 1374, 1375, 1379, 1379, 1380, 1380, 1385, 1388, - 1398, 1401, 1407, 1408, 1412, 1420, 1424, 1431, 1431, 1438, - 1441, 1448, 1453, 1468, 1468, 1473, 1473, 1480, 1480, 1488, - 1491, 1497, 1500, 1506, 1510, 1517, 1520, 1523, 1526, 1529, - 1538, 1542, 1549, 1552, 1558, 1558 + 0, 236, 236, 237, 240, 250, 253, 258, 263, 268, + 273, 279, 282, 285, 288, 291, 294, 300, 307, 318, + 322, 330, 333, 339, 343, 350, 356, 365, 373, 379, + 385, 394, 397, 400, 403, 413, 414, 415, 416, 424, + 425, 428, 431, 438, 439, 442, 448, 449, 453, 460, + 461, 464, 467, 470, 476, 477, 480, 486, 487, 494, + 495, 502, 503, 510, 511, 517, 518, 524, 525, 531, + 532, 538, 539, 546, 547, 548, 549, 553, 554, 555, + 559, 563, 567, 571, 578, 581, 587, 594, 601, 604, + 610, 619, 623, 627, 631, 635, 642, 649, 652, 659, + 667, 687, 697, 705, 730, 734, 738, 742, 749, 756, + 759, 763, 767, 772, 777, 784, 788, 792, 796, 801, + 806, 813, 823, 829, 832, 838, 842, 849, 855, 862, + 866, 869, 872, 881, 887, 895, 898, 918, 937, 944, + 948, 955, 965, 968, 971, 977, 984, 987, 993, 996, + 999, 1005, 1008, 1013, 1024, 1027, 1030, 1033, 1036, 1039, + 1043, 1047, 1051, 1055, 1059, 1063, 1067, 1071, 1075, 1079, + 1083, 1087, 1091, 1095, 1099, 1103, 1107, 1111, 1115, 1119, + 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, + 1153, 1156, 1159, 1162, 1165, 1168, 1175, 1181, 1184, 1196, + 1196, 1199, 1199, 1205, 1208, 1223, 1226, 1233, 1237, 1243, + 1249, 1261, 1265, 1269, 1270, 1276, 1277, 1278, 1279, 1280, + 1281, 1282, 1286, 1287, 1287, 1287, 1297, 1298, 1302, 1302, + 1303, 1303, 1308, 1311, 1321, 1324, 1330, 1331, 1335, 1342, + 1346, 1353, 1353, 1360, 1363, 1370, 1374, 1387, 1387, 1392, + 1392, 1398, 1398, 1406, 1409, 1415, 1418, 1424, 1428, 1435, + 1438, 1441, 1444, 1447, 1456, 1460, 1467, 1470, 1476, 1476 }; #endif @@ -770,10 +786,10 @@ static const char *const yytname[] = "constant_expression", "enter_struct", "declaration", "function_prototype", "function_declarator", "function_header_with_parameters", "function_header", - "parameter_declarator", "parameter_declaration", "parameter_qualifier", + "parameter_declarator", "parameter_declaration", "parameter_type_specifier", "init_declarator_list", "single_declaration", - "fully_specified_type", "interpolation_qualifier", - "parameter_type_qualifier", "type_qualifier", "storage_qualifier", + "fully_specified_type", "interpolation_qualifier", "type_qualifier", + "invariant_qualifier", "single_type_qualifier", "storage_qualifier", "type_specifier", "precision_qualifier", "layout_qualifier", "layout_qualifier_id_list", "layout_qualifier_id", "type_specifier_no_prec", "type_specifier_nonarray", "struct_specifier", @@ -812,12 +828,12 @@ static const yytype_uint16 yytoknum[] = }; # endif -#define YYPACT_NINF -361 +#define YYPACT_NINF -348 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-361))) + (!!((Yystate) == (-348))) -#define YYTABLE_NINF -235 +#define YYTABLE_NINF -229 #define yytable_value_is_error(Yytable_value) \ 0 @@ -826,48 +842,47 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - 2154, 224, -361, -361, -361, 130, -361, -361, -361, -361, - -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, - -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, - -361, -361, -361, -361, -361, -361, -361, 145, -361, -361, - -46, -361, -361, -361, -361, -361, -361, -361, -361, -361, - -361, -361, -361, -361, -361, -361, -361, -361, -361, -82, - -361, -361, -68, -41, -45, 9, 7, -361, 117, 16, - 1173, -361, -361, 2439, 16, -361, -9, -361, 2079, -361, - -361, -361, -361, 16, -361, 2439, -361, -361, -361, -361, - -361, -31, 23, -361, 11, -361, 63, -361, -361, -361, - -361, -361, 2303, 168, 120, -361, 13, -66, -361, 31, - -361, 2229, -361, -361, -361, 1243, -361, -361, -361, 56, - 2229, -361, 17, -50, -361, 401, -361, -361, -361, -361, - 120, 2303, -18, -361, 1341, 1632, -361, 179, 2303, 120, - 1824, -361, 70, -361, -361, -361, -361, -361, 1632, 1632, - 1632, -361, -361, -361, -361, -361, -361, -361, 22, -361, - -361, -361, 101, -29, 1727, 114, -361, 1632, 96, -97, - 128, -54, 111, 118, 102, 115, 154, 153, -69, -361, - 140, -361, -361, 1909, 2229, 124, -361, 23, 134, 136, - -361, 147, 149, 143, 1439, 155, 1632, 148, 157, 160, - -361, -361, 184, -361, -361, 52, -361, -68, 158, -361, - -361, -361, -361, 517, -361, -361, -361, -361, -361, -361, - 166, -361, -361, 1534, 1632, 150, 159, -361, -361, 120, - 167, 61, -361, -62, -361, -361, -361, -5, -361, -361, - 1632, 2371, -361, -361, 1632, 185, -361, -361, -361, 1632, - 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, - 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, -361, - -361, 1994, -361, -361, -361, -361, -361, 181, -361, 1632, - -361, -361, 67, 1632, 180, -361, -361, -361, 633, -361, - -361, -361, -361, -361, -361, -361, -361, -361, -361, -361, - 1632, 1632, -361, -361, -361, 1632, 178, 186, -361, 1632, - 182, 68, 1632, 120, -361, -71, -361, -361, 187, 188, - -361, 192, -361, -361, -361, -361, -361, 96, 96, -97, - -97, 128, 128, 128, 128, -54, -54, 111, 118, 102, - 115, 154, 153, 113, -361, 242, 11, 865, 981, 4, - -361, 18, -361, 1078, 633, -361, -361, 194, 1632, 189, - -361, 1632, -361, 196, -361, 1632, -361, -361, 1632, 200, - -361, -361, -361, -361, 1078, 181, -361, 188, 120, 2303, - 201, 198, -361, -361, 1632, -361, -361, 202, -361, 1632, - -361, 191, 203, 293, -361, 204, 205, 749, -361, -361, - 197, 60, 1632, 749, 181, -361, 1632, -361, -361, -361, - -361, 199, 188, -361, -361, -361, -361 + 2144, -348, -348, -348, -348, 144, -348, -348, -348, -348, + -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, + -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, + -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, + -348, -53, -348, -348, -348, -348, -348, -348, -348, -348, + -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, + -83, -348, -348, -89, -70, -81, 2219, -26, -348, 60, + -348, 1163, -348, -348, -348, -348, -348, -348, -348, -66, + -348, 2069, -348, -348, 2355, -348, -348, -348, -41, -2, + -348, -30, -348, 2219, -348, -348, -348, 2219, 80, 80, + -348, -17, -75, -65, -348, 2219, -348, -348, 1233, -348, + -348, -15, 2219, -348, -10, -85, -348, 389, -348, -348, + -348, -348, 1, -49, -348, 1331, 1622, -348, -348, 2219, + 80, 1814, -348, 19, -348, -348, -348, -348, -348, 1622, + 1622, 1622, -348, -348, -348, -348, -348, -348, -348, -24, + -348, -348, -348, 37, -22, 1717, 67, -348, 1622, 34, + 14, 76, -46, 72, 51, 75, 78, 112, 113, -77, + -348, 98, -348, -348, 1899, 2219, 84, -348, -2, 94, + 97, -348, 108, 109, 100, 1429, 114, 1622, 104, 115, + 111, -348, -348, 190, -348, -348, -19, -348, -89, 117, + -348, -348, -348, -348, 505, -348, -348, -348, -348, -348, + -348, 1622, 1524, 1622, 116, 110, -348, -348, 80, 118, + 27, -348, -58, -348, -348, -348, -5, -348, -348, 1622, + 2287, -348, -348, 1622, 121, -348, -348, -348, 1622, 1622, + 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, + 1622, 1622, 1622, 1622, 1622, 1622, 1622, 1622, -348, -348, + 1984, -348, -348, -348, -348, -348, 119, -348, 1622, -348, + -348, 32, 1622, 122, -348, -348, -348, 621, -348, -348, + -348, -348, -348, -348, -348, -348, -348, -348, -348, 1622, + 1622, -348, -348, -348, 124, 120, 129, -348, 1622, 125, + 33, 1622, 80, -348, -87, -348, -348, 130, 128, -348, + 136, -348, -348, -348, -348, -348, 34, 34, 14, 14, + 76, 76, 76, 76, -46, -46, 72, 51, 75, 78, + 112, 113, 54, -348, 166, -30, 853, 969, -3, -348, + -1, -348, 1066, 621, -348, -348, -348, 1622, 132, -348, + 1622, -348, 135, -348, 1622, -348, -348, 1622, 139, -348, + -348, -348, -348, 1066, 119, -348, 128, 80, 2219, 141, + 140, -348, 1622, -348, -348, 145, -348, 1622, -348, 134, + 146, 236, -348, 147, 143, 737, -348, -348, 148, 17, + 1622, 737, 119, -348, 1622, -348, -348, -348, -348, 149, + 128, -348, -348, -348, -348 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -875,78 +890,77 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 0, 148, 149, 150, 0, 130, 140, 164, 161, - 162, 163, 168, 169, 170, 171, 172, 173, 165, 166, - 167, 174, 175, 176, 177, 178, 179, 141, 142, 145, - 131, 180, 181, 182, 183, 184, 185, 0, 128, 127, - 0, 160, 186, 188, 201, 202, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 187, 198, 199, 200, 0, - 204, 273, 274, 0, 97, 107, 0, 112, 118, 135, - 0, 133, 125, 0, 136, 146, 157, 203, 0, 270, - 272, 132, 124, 0, 138, 0, 143, 144, 2, 3, - 207, 0, 0, 88, 0, 95, 107, 129, 108, 109, - 110, 98, 0, 107, 0, 89, 2, 119, 134, 0, - 94, 0, 126, 147, 137, 0, 1, 271, 139, 0, - 0, 205, 154, 0, 152, 0, 275, 99, 104, 106, - 111, 0, 113, 100, 0, 0, 87, 0, 0, 0, - 0, 209, 4, 8, 6, 7, 9, 30, 0, 0, - 0, 158, 37, 36, 38, 35, 5, 11, 31, 13, - 18, 19, 0, 0, 24, 0, 39, 0, 43, 46, - 49, 54, 57, 59, 61, 63, 65, 67, 69, 86, - 0, 28, 90, 0, 0, 0, 151, 0, 0, 0, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 229, - 238, 242, 39, 71, 84, 0, 218, 0, 146, 221, - 240, 220, 219, 0, 222, 223, 224, 225, 226, 227, - 101, 103, 105, 0, 0, 0, 0, 217, 123, 0, - 215, 0, 213, 0, 210, 32, 33, 0, 15, 16, - 0, 0, 22, 21, 0, 160, 25, 27, 34, 0, + 0, 127, 142, 143, 144, 0, 133, 135, 158, 155, + 156, 157, 162, 163, 164, 165, 166, 167, 159, 160, + 161, 168, 169, 170, 171, 172, 173, 136, 137, 138, + 140, 134, 174, 175, 176, 177, 178, 179, 139, 124, + 123, 0, 154, 180, 182, 195, 196, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 181, 192, 193, 194, + 0, 198, 267, 268, 0, 98, 97, 0, 109, 115, + 131, 0, 132, 125, 128, 121, 130, 129, 141, 151, + 197, 0, 264, 266, 0, 2, 3, 201, 0, 0, + 88, 0, 96, 0, 105, 99, 107, 0, 108, 0, + 89, 2, 116, 0, 94, 0, 126, 122, 0, 1, + 265, 0, 0, 199, 148, 0, 146, 0, 269, 100, + 104, 106, 102, 110, 101, 0, 0, 87, 95, 0, + 0, 0, 203, 4, 8, 6, 7, 9, 30, 0, + 0, 0, 152, 37, 36, 38, 35, 5, 11, 31, + 13, 18, 19, 0, 0, 24, 0, 39, 0, 43, + 46, 49, 54, 57, 59, 61, 63, 65, 67, 69, + 86, 0, 28, 90, 0, 0, 0, 145, 0, 0, + 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, + 223, 232, 236, 39, 71, 84, 0, 212, 0, 141, + 215, 234, 214, 213, 0, 216, 217, 218, 219, 220, + 221, 0, 0, 0, 0, 0, 211, 120, 0, 209, + 0, 207, 0, 204, 32, 33, 0, 15, 16, 0, + 0, 22, 21, 0, 154, 25, 27, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, - 208, 0, 155, 156, 153, 266, 265, 236, 257, 0, - 269, 267, 0, 0, 0, 250, 253, 228, 0, 74, - 75, 77, 76, 79, 80, 81, 82, 83, 78, 73, - 0, 0, 243, 239, 241, 0, 0, 0, 117, 0, - 120, 0, 0, 0, 211, 0, 91, 10, 0, 17, - 29, 14, 20, 26, 40, 41, 42, 45, 44, 47, - 48, 52, 53, 50, 51, 55, 56, 58, 60, 62, - 64, 66, 68, 0, 206, 0, 0, 0, 0, 0, - 268, 0, 249, 0, 230, 72, 85, 0, 0, 114, - 121, 0, 212, 0, 214, 0, 92, 12, 0, 0, - 235, 237, 260, 259, 262, 236, 247, 251, 0, 0, - 0, 0, 102, 115, 0, 122, 216, 0, 70, 0, - 261, 0, 0, 246, 244, 0, 0, 0, 231, 116, - 0, 0, 263, 0, 236, 248, 0, 233, 254, 232, - 93, 0, 264, 258, 245, 252, 256 + 0, 0, 0, 0, 0, 0, 0, 0, 153, 202, + 0, 149, 150, 147, 260, 259, 230, 251, 0, 263, + 261, 0, 0, 0, 244, 247, 222, 0, 74, 75, + 77, 76, 79, 80, 81, 82, 83, 78, 73, 0, + 0, 237, 233, 235, 0, 0, 0, 114, 0, 117, + 0, 0, 0, 205, 0, 91, 10, 0, 17, 29, + 14, 20, 26, 40, 41, 42, 45, 44, 47, 48, + 52, 53, 50, 51, 55, 56, 58, 60, 62, 64, + 66, 68, 0, 200, 0, 0, 0, 0, 0, 262, + 0, 243, 0, 224, 72, 85, 103, 0, 111, 118, + 0, 206, 0, 208, 0, 92, 12, 0, 0, 229, + 231, 254, 253, 256, 230, 241, 245, 0, 0, 0, + 0, 112, 0, 119, 210, 0, 70, 0, 255, 0, + 0, 240, 238, 0, 0, 0, 225, 113, 0, 0, + 257, 0, 230, 242, 0, 227, 248, 226, 93, 0, + 258, 252, 239, 246, 250 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -361, -39, -361, -361, -361, -361, -361, -361, 73, -361, - -361, -361, -361, -107, -361, -15, -20, -67, -19, 53, - 54, 55, 51, 57, 58, -361, -110, -132, -361, -146, - -125, -361, 6, 12, -361, -361, -361, 190, 228, 217, - 195, -361, -361, -336, 25, -361, -104, 27, -57, 322, - -361, -361, 141, 0, -361, -361, -361, -361, -109, -130, - 100, 19, -185, -17, -193, -310, -65, -361, -361, -70, - -360, -361, -361, -92, 46, -13, -361, -361, -361, -361, - -361, -38, -361, -361, -361, -361, -361, -361, -361, -361, - -361, 259, -361, -361 + -348, -40, -348, -348, -348, -348, -348, -348, 28, -348, + -348, -348, -348, -60, -348, -72, -71, -127, -52, 8, + 12, 16, 7, 10, 11, -348, -86, -122, -348, -133, + -78, -348, 9, 13, -348, -348, -348, 169, 177, 174, + -348, -348, -326, -348, -59, -348, -69, -348, -61, 268, + -348, -348, 96, 0, -348, -348, -348, -348, -100, -120, + 57, -23, -140, -57, -198, -322, -105, -348, -348, -110, + -347, -348, -348, -88, 5, -42, -348, -348, -348, -348, + -348, -67, -348, -348, -348, -348, -348, -348, -348, -348, + -348, 216, -348, -348 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 230, 156, 157, 158, 318, 159, 160, 161, 162, - 163, 164, 165, 202, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 203, 204, 300, 205, - 180, 111, 206, 207, 63, 64, 65, 128, 101, 102, - 129, 66, 67, 68, 69, 103, 70, 71, 72, 73, - 74, 123, 124, 181, 76, 77, 184, 120, 140, 141, - 231, 232, 228, 209, 210, 211, 212, 288, 381, 408, - 345, 346, 347, 409, 213, 214, 215, 394, 216, 395, - 217, 380, 218, 353, 277, 348, 374, 391, 392, 219, - 78, 79, 80, 94 + -1, 219, 147, 148, 149, 307, 150, 151, 152, 153, + 154, 155, 156, 193, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 194, 195, 289, 196, + 171, 105, 197, 198, 64, 65, 66, 94, 95, 96, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 115, 116, 172, 79, 80, 175, 112, 131, 132, + 220, 221, 217, 200, 201, 202, 203, 277, 370, 396, + 334, 335, 336, 397, 204, 205, 206, 382, 207, 383, + 208, 369, 209, 342, 266, 337, 363, 379, 380, 210, + 81, 82, 83, 91 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -954,387 +968,378 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 75, 91, 126, 227, 237, 179, 61, 138, 166, 226, - 234, 183, 62, 112, 315, 393, 138, 378, 97, 252, - 304, 253, 92, 267, 179, 7, 83, 166, 84, 107, - 88, 89, 246, 256, 257, 365, 138, 371, 378, 308, - 134, 235, 236, 366, 414, 130, 93, 135, 282, 98, - 99, 100, 316, 234, 139, 186, 27, 28, 268, 29, - 248, 187, 90, 139, 95, 132, 96, 37, 258, 259, - 75, 284, 97, 113, 130, 271, 243, 121, 75, 138, - 138, 229, 244, 139, 61, 119, 179, 407, 223, 166, - 62, 220, 227, 407, 319, 224, 108, 115, 307, 122, - 317, 114, 75, 98, 99, 100, 301, 238, 239, 375, - 118, 75, 323, 179, -96, 301, 166, 133, 104, 125, - 75, 105, 343, 376, 360, 208, 139, 139, 240, 301, - 185, 75, 241, 349, 2, 3, 4, 351, 75, 136, - 75, 234, 324, 325, 326, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 304, 83, 301, 84, 411, 302, 138, 355, 356, - 182, 301, 313, 383, -29, 314, 385, 227, 301, 313, - 357, 350, 362, 75, 75, 86, 87, 363, 7, 331, - 332, 333, 334, 106, 89, 179, 88, 89, 166, 399, - 260, 261, 179, 272, 273, 166, 242, 377, 98, 99, - 100, 254, 255, 208, 139, 249, 250, 251, 247, 27, - 28, 415, 29, 81, 301, 368, 227, 263, 377, 227, - 37, 38, 39, 7, 329, 330, 388, 327, 328, 264, - 387, 335, 336, 401, 262, 265, 266, 269, 275, 379, - 276, 278, 227, 279, 370, 179, 412, 280, 166, 283, - 285, 286, -28, 309, 27, 28, 310, 29, 81, 287, - 379, 75, 305, 312, 227, 37, 38, 39, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 208, -234, - -23, 358, 352, 359, 367, 361, -30, 299, 369, 301, - 82, 382, 384, 386, 389, 402, 397, 398, 403, 400, - 404, 410, 199, 416, 322, 337, 340, 338, 406, 339, - 131, 221, 112, 341, 127, 342, 222, 85, 274, 311, - 405, 372, 364, 413, 354, 373, 390, 117, 0, 396, - 0, 0, 0, 0, 0, 0, 0, 208, 208, 0, - 0, 0, 0, 208, 208, 0, 0, 0, 0, 0, + 78, 88, 106, 118, 216, 98, 293, 97, 226, 62, + 107, 223, 174, 63, 360, 256, 367, 381, 304, 354, + 177, 89, 170, 85, 86, 90, 178, 355, 106, 102, + 93, 125, 98, 235, 97, 92, 98, 367, 126, 170, + 108, 245, 246, 127, 130, 402, 129, 215, 157, 128, + 257, 130, 271, 129, 223, 87, 305, 212, 122, 123, + 106, 227, 228, 395, 213, 157, 78, 113, 218, 395, + 130, 78, 129, 297, 114, 260, 247, 248, 117, 224, + 225, 78, 229, 232, 111, 99, 230, 124, 100, 233, + 62, 216, 290, 78, 63, 291, 308, 78, 237, 173, + 306, 170, 364, 176, 365, 78, 290, 211, 290, 273, + 290, 312, 78, 130, 130, 129, 129, 199, 320, 321, + 322, 323, 399, -29, 332, 170, 170, 157, 290, 78, + 241, 78, 242, 294, 296, 338, 101, 86, 302, 340, + 223, 303, 231, 290, 302, 293, 339, 351, 2, 3, + 4, 157, 157, 238, 239, 240, 85, 86, 349, 243, + 244, 249, 250, 261, 262, 290, 357, 344, 345, 316, + 317, 236, 318, 319, 78, 78, 216, 251, 313, 314, + 315, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 324, 325, 130, + 252, 129, 253, 254, 199, 258, 255, 371, 264, 366, + 373, 265, 267, 268, 269, 170, 274, 299, 272, 275, + 276, -28, 358, 352, 301, 216, -23, -228, 216, 298, + 366, 346, 387, 347, 341, 376, 348, 356, 350, 290, + -30, 157, 374, 377, 389, 372, 385, 359, 390, 386, + 216, 391, 388, 392, 403, 190, 394, 400, 311, 326, + 78, 329, 398, 404, 327, 330, 120, 331, 170, 328, + 119, 121, 216, 84, 263, 300, 375, 199, 393, 353, + 361, 401, 343, 368, 278, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 157, 362, 378, 110, 0, 106, + 0, 0, 0, 288, 368, 0, 0, 107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, + 0, 0, 0, 0, 0, 0, 199, 199, 0, 0, + 0, 0, 199, 199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 208, 0, 0, 0, 0, 75, + 0, 0, 0, 199, 0, 0, 0, 0, 78, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 199, 0, 0, 0, 0, + 0, 199, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 179, 180, 181, 0, 182, 183, 184, + 185, 186, 187, 188, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 189, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 0, 57, 58, 59, 60, 133, 61, 134, 135, 136, + 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, - 0, 0, 0, 208, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 188, 189, 190, 0, 191, - 192, 193, 194, 195, 196, 197, 12, 13, 14, 15, + 0, 0, 0, 141, 0, 0, 0, 190, 191, 0, + 0, 0, 0, 192, 143, 144, 145, 146, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 179, + 180, 181, 0, 182, 183, 184, 185, 186, 187, 188, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 189, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 0, 57, 58, 59, + 60, 133, 61, 134, 135, 136, 137, 138, 0, 0, + 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, + 0, 0, 0, 190, 292, 0, 0, 0, 0, 192, + 143, 144, 145, 146, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 179, 180, 181, 0, 182, + 183, 184, 185, 186, 187, 188, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 198, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 59, 142, 60, 143, - 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 189, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 0, 57, 58, 59, 60, 133, 61, 134, + 135, 136, 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 150, 0, 0, 0, 199, - 200, 0, 0, 0, 0, 201, 152, 153, 154, 155, + 0, 0, 0, 0, 0, 141, 0, 0, 0, 190, + 0, 0, 0, 0, 0, 192, 143, 144, 145, 146, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 188, 189, 190, 0, 191, 192, 193, 194, 195, - 196, 197, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 198, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 0, 56, - 57, 58, 59, 142, 60, 143, 144, 145, 146, 147, - 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, + 11, 179, 180, 181, 0, 182, 183, 184, 185, 186, + 187, 188, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 189, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 0, 57, + 58, 59, 60, 133, 61, 134, 135, 136, 137, 138, + 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 150, 0, 0, 0, 199, 303, 0, 0, 0, - 0, 201, 152, 153, 154, 155, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 188, 189, 190, - 0, 191, 192, 193, 194, 195, 196, 197, 12, 13, + 0, 141, 0, 0, 0, 117, 0, 0, 0, 0, + 0, 192, 143, 144, 145, 146, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 179, 180, 181, + 0, 182, 183, 184, 185, 186, 187, 188, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 0, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 198, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 0, 56, 57, 58, 59, 142, - 60, 143, 144, 145, 146, 147, 0, 0, 148, 149, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 189, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 0, 57, 58, 59, 60, 133, + 61, 134, 135, 136, 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, - 0, 199, 0, 0, 0, 0, 0, 201, 152, 153, - 154, 155, 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 188, 189, 190, 0, 191, 192, 193, - 194, 195, 196, 197, 12, 13, 14, 15, 16, 17, + 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 192, 143, 144, + 145, 146, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 198, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 59, 142, 60, 143, 144, 145, - 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 0, 0, 0, 125, 0, 0, - 0, 0, 0, 201, 152, 153, 154, 155, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 188, - 189, 190, 0, 191, 192, 193, 194, 195, 196, 197, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 0, 29, 30, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 0, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 0, 57, 58, 59, 60, 133, 61, 134, 135, 136, + 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 2, 3, 4, 141, 6, 7, 8, 9, 10, 11, + 0, 0, 0, 192, 143, 144, 145, 146, 0, 0, + 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 198, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 0, 56, 57, 58, - 59, 142, 60, 143, 144, 145, 146, 147, 0, 0, - 148, 149, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, - 152, 153, 154, 155, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 0, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 59, 142, 60, 143, - 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 137, 2, 3, 4, 150, 6, 7, 8, 9, - 10, 11, 0, 0, 0, 201, 152, 153, 154, 155, - 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 0, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 0, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, - 56, 57, 58, 59, 142, 60, 143, 144, 145, 146, - 147, 0, 0, 148, 149, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, - 0, 0, 150, 8, 9, 10, 11, 0, 0, 0, - 0, 0, 0, 152, 153, 154, 155, 0, 12, 13, + 41, 42, 0, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 0, 57, 58, + 59, 60, 133, 61, 134, 135, 136, 137, 138, 0, + 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 141, 6, 7, 8, 9, 10, 11, 0, 0, 0, + 0, 143, 144, 145, 146, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 0, 0, 0, 31, 32, - 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 0, 56, 57, 58, 0, 109, - 60, 0, 0, 8, 9, 10, 11, 0, 0, 0, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 0, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 0, 57, 58, 59, 60, 103, + 61, 0, 0, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 0, 0, 110, 31, 32, - 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 0, 56, 57, 58, 0, 142, - 60, 143, 144, 145, 146, 147, 0, 0, 148, 149, + 24, 25, 26, 0, 0, 0, 0, 104, 32, 33, + 34, 35, 36, 37, 0, 0, 0, 41, 42, 0, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 0, 57, 58, 59, 0, 133, + 61, 134, 135, 136, 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, - 151, 8, 9, 10, 11, 0, 0, 0, 152, 153, - 154, 155, 0, 0, 0, 0, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, + 142, 8, 9, 10, 11, 0, 0, 0, 143, 144, + 145, 146, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 0, 0, 0, 0, 0, 31, 32, 33, 34, - 35, 36, 0, 0, 0, 40, 41, 0, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 0, 142, 60, 143, - 144, 145, 146, 147, 0, 0, 148, 149, 0, 0, + 26, 0, 0, 0, 0, 0, 32, 33, 34, 35, + 36, 37, 0, 0, 0, 41, 42, 0, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 0, 57, 58, 59, 0, 133, 61, 134, + 135, 136, 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 150, 0, 0, 225, 8, - 9, 10, 11, 0, 0, 0, 152, 153, 154, 155, + 0, 0, 0, 0, 0, 141, 0, 0, 214, 8, + 9, 10, 11, 0, 0, 0, 143, 144, 145, 146, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, - 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, - 0, 0, 0, 40, 41, 0, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 0, 142, 60, 143, 144, 145, - 146, 147, 0, 0, 148, 149, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 33, 34, 35, 36, 37, + 0, 0, 0, 41, 42, 0, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 0, 57, 58, 59, 0, 133, 61, 134, 135, 136, + 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 8, 9, 10, 11, 0, 0, - 0, 0, 0, 281, 152, 153, 154, 155, 0, 12, + 0, 0, 0, 141, 8, 9, 10, 11, 0, 0, + 0, 0, 0, 270, 143, 144, 145, 146, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 0, 0, 0, 0, 0, 31, - 32, 33, 34, 35, 36, 0, 0, 0, 40, 41, - 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 0, 56, 57, 58, 0, - 142, 60, 143, 144, 145, 146, 147, 0, 0, 148, - 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 150, 0, - 0, 306, 8, 9, 10, 11, 0, 0, 0, 152, - 153, 154, 155, 0, 0, 0, 0, 12, 13, 14, + 23, 24, 25, 26, 0, 0, 0, 0, 0, 32, + 33, 34, 35, 36, 37, 0, 0, 0, 41, 42, + 0, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 0, 57, 58, 59, 0, + 133, 61, 134, 135, 136, 137, 138, 0, 0, 139, + 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 141, 0, + 0, 295, 8, 9, 10, 11, 0, 0, 0, 143, + 144, 145, 146, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 0, 0, 0, 0, 0, 31, 32, 33, - 34, 35, 36, 0, 0, 0, 40, 41, 0, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 0, 56, 57, 58, 0, 142, 60, - 143, 144, 145, 146, 147, 0, 0, 148, 149, 0, + 25, 26, 0, 0, 0, 0, 0, 32, 33, 34, + 35, 36, 37, 0, 0, 0, 41, 42, 0, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 0, 57, 58, 59, 0, 133, 61, + 134, 135, 136, 137, 138, 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 150, 8, 9, 10, - 11, 0, 0, 0, 0, 0, 0, 152, 153, 154, - 155, 0, 12, 13, 14, 15, 16, 17, 18, 19, + 0, 0, 0, 0, 0, 0, 141, 8, 9, 10, + 11, 0, 0, 0, 0, 0, 0, 143, 144, 145, + 146, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, 0, 0, - 0, 0, 31, 32, 33, 34, 35, 36, 0, 0, - 0, 40, 245, 0, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 0, 56, - 57, 58, 0, 142, 60, 143, 144, 145, 146, 147, - 0, 0, 148, 149, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 137, 2, 3, - 4, 150, 6, 7, 8, 9, 10, 11, 0, 0, - 0, 0, 152, 153, 154, 155, 0, 0, 0, 12, + 0, 0, 32, 33, 34, 35, 36, 37, 0, 0, + 0, 41, 234, 0, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 0, 57, + 58, 59, 0, 133, 61, 134, 135, 136, 137, 138, + 0, 0, 139, 140, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, 141, 6, 7, 8, 9, 10, 11, 0, 0, + 0, 0, 143, 144, 145, 146, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, - 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 137, 2, 3, 4, 0, 6, 7, 8, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 0, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 0, 57, 58, 59, 60, + 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 0, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 233, 12, 13, 14, 15, 16, 17, + 0, 0, 0, 222, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 0, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 59, 0, 60, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 137, 2, 3, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 0, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 0, 57, 58, 59, 60, 0, 61, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 6, 7, 8, 9, 10, 11, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 12, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, - 0, 60, 0, 0, 0, 0, 0, 0, 0, 116, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 0, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 0, 57, 58, 59, 60, + 0, 61, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 344, 12, 13, 14, 15, 16, 17, + 0, 0, 0, 333, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 0, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 59, 0, 60, 1, 2, 3, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 0, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 0, 57, 58, 59, 60, 0, 61, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 0, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 0, 56, 57, 58, 59, - 0, 60, 137, 2, 3, 4, 0, 6, 7, 8, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 0, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 0, 57, 58, 59, 60, + 0, 61, 1, 2, 3, 4, 0, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 0, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 0, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 59, 0, 60, 2, 3, 4, - 0, 0, 0, 8, 9, 10, 11, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 0, 0, 0, 0, 0, 31, 32, - 33, 34, 35, 36, 0, 0, 0, 40, 41, 0, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 0, 56, 57, 58, 0, 0, - 60, 8, 9, 10, 11, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 0, 0, 0, 0, 0, 31, 32, 33, 34, - 35, 36, 0, 0, 0, 40, 41, 0, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 0, 56, 57, 58, 0, 320, 60, 8, - 9, 10, 11, 321, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, - 0, 0, 0, 0, 31, 32, 33, 34, 35, 36, - 0, 0, 0, 40, 41, 0, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 0, 56, 57, 58, 0, 0, 60 + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 0, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 0, 57, 58, 59, 60, 0, 61, 8, 9, 10, + 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 0, 0, 0, + 0, 0, 32, 33, 34, 35, 36, 37, 0, 0, + 0, 41, 42, 0, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 0, 57, + 58, 59, 0, 309, 61, 8, 9, 10, 11, 310, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 0, 0, 0, 0, 0, + 32, 33, 34, 35, 36, 37, 0, 0, 0, 41, + 42, 0, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 0, 57, 58, 59, + 0, 0, 61 }; static const yytype_int16 yycheck[] = { - 0, 40, 94, 135, 150, 115, 0, 111, 115, 134, - 140, 120, 0, 70, 76, 375, 120, 353, 9, 116, - 213, 118, 104, 92, 134, 9, 1, 134, 1, 68, - 76, 77, 164, 87, 88, 106, 140, 347, 374, 224, - 106, 148, 149, 114, 404, 102, 114, 113, 194, 40, - 41, 42, 114, 183, 111, 105, 40, 41, 127, 43, - 167, 111, 108, 120, 105, 104, 111, 51, 122, 123, - 70, 196, 9, 73, 131, 184, 105, 108, 78, 183, - 184, 138, 111, 140, 78, 85, 196, 397, 106, 196, - 78, 130, 224, 403, 240, 113, 69, 106, 223, 76, - 105, 74, 102, 40, 41, 42, 111, 85, 86, 105, - 83, 111, 244, 223, 105, 111, 223, 104, 111, 108, - 120, 114, 268, 105, 309, 125, 183, 184, 106, 111, - 113, 131, 110, 279, 4, 5, 6, 283, 138, 108, - 140, 271, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 354, 137, 111, 137, 105, 114, 271, 300, 301, - 114, 111, 111, 358, 104, 114, 361, 309, 111, 111, - 305, 114, 114, 183, 184, 40, 41, 312, 9, 256, - 257, 258, 259, 76, 77, 305, 76, 77, 305, 384, - 89, 90, 312, 79, 80, 312, 105, 353, 40, 41, - 42, 83, 84, 213, 271, 119, 120, 121, 104, 40, - 41, 406, 43, 44, 111, 112, 358, 125, 374, 361, - 51, 52, 53, 9, 254, 255, 368, 252, 253, 124, - 365, 260, 261, 389, 126, 91, 93, 107, 114, 353, - 114, 104, 384, 104, 346, 365, 402, 114, 365, 104, - 112, 104, 104, 113, 40, 41, 107, 43, 44, 109, - 374, 271, 106, 106, 406, 51, 52, 53, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 288, 108, - 105, 113, 112, 107, 107, 113, 104, 113, 56, 111, - 76, 107, 113, 107, 104, 114, 105, 109, 105, 107, - 17, 114, 108, 114, 241, 262, 265, 263, 113, 264, - 103, 131, 379, 266, 96, 267, 131, 5, 187, 229, - 395, 348, 313, 403, 288, 348, 374, 78, -1, 378, - -1, -1, -1, -1, -1, -1, -1, 347, 348, -1, - -1, -1, -1, 353, 354, -1, -1, -1, -1, -1, + 0, 41, 71, 91, 126, 66, 204, 66, 141, 0, + 71, 131, 112, 0, 336, 92, 342, 364, 76, 106, + 105, 104, 108, 76, 77, 114, 111, 114, 97, 69, + 111, 106, 93, 155, 93, 105, 97, 363, 113, 125, + 106, 87, 88, 108, 105, 392, 105, 125, 108, 114, + 127, 112, 185, 112, 174, 108, 114, 106, 98, 99, + 129, 85, 86, 385, 113, 125, 66, 108, 129, 391, + 131, 71, 131, 213, 76, 175, 122, 123, 108, 139, + 140, 81, 106, 105, 84, 111, 110, 104, 114, 111, + 81, 213, 111, 93, 81, 114, 229, 97, 158, 114, + 105, 187, 105, 113, 105, 105, 111, 106, 111, 187, + 111, 233, 112, 174, 175, 174, 175, 117, 245, 246, + 247, 248, 105, 104, 257, 211, 212, 187, 111, 129, + 116, 131, 118, 211, 212, 268, 76, 77, 111, 272, + 260, 114, 105, 111, 111, 343, 114, 114, 4, 5, + 6, 211, 212, 119, 120, 121, 76, 77, 298, 83, + 84, 89, 90, 79, 80, 111, 112, 289, 290, 241, + 242, 104, 243, 244, 174, 175, 298, 126, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 249, 250, 260, + 125, 260, 124, 91, 204, 107, 93, 347, 114, 342, + 350, 114, 104, 104, 114, 301, 112, 107, 104, 104, + 109, 104, 56, 301, 106, 347, 105, 108, 350, 113, + 363, 107, 372, 113, 112, 357, 107, 107, 113, 111, + 104, 301, 107, 104, 377, 113, 105, 335, 114, 109, + 372, 105, 107, 17, 394, 108, 113, 390, 230, 251, + 260, 254, 114, 114, 252, 255, 97, 256, 354, 253, + 93, 97, 394, 5, 178, 218, 354, 277, 383, 302, + 337, 391, 277, 342, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 354, 337, 363, 81, -1, 368, + -1, -1, -1, 113, 363, -1, -1, 368, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 367, -1, -1, + -1, -1, -1, -1, -1, -1, 336, 337, -1, -1, + -1, -1, 342, 343, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 374, -1, -1, -1, -1, 379, + -1, -1, -1, 363, -1, -1, -1, -1, 368, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 385, -1, -1, -1, -1, + -1, 391, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 397, -1, -1, - -1, -1, -1, 403, 3, 4, 5, 6, 7, 8, + -1, -1, -1, 104, -1, -1, -1, 108, 109, -1, + -1, -1, -1, 114, 115, 116, 117, 118, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, + 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, + -1, -1, -1, 108, 109, -1, -1, -1, -1, 114, + 115, 116, 117, 118, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, -1, 108, - 109, -1, -1, -1, -1, 114, 115, 116, 117, 118, + -1, -1, -1, -1, -1, 114, 115, 116, 117, 118, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, -1, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 104, -1, -1, -1, 108, 109, -1, -1, -1, + -1, 104, -1, -1, -1, 108, -1, -1, -1, -1, -1, 114, 115, 116, 117, 118, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, -1, 43, 44, 45, 46, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, - -1, 108, -1, -1, -1, -1, -1, 114, 115, 116, + -1, -1, -1, -1, -1, -1, -1, 114, 115, 116, 117, 118, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, -1, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 104, -1, -1, -1, 108, -1, -1, - -1, -1, -1, 114, 115, 116, 117, 118, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, -1, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, -1, -1, - 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 114, - 115, 116, 117, 118, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, -1, -1, 85, 86, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 3, 4, 5, 6, 104, 8, 9, 10, 11, - 12, 13, -1, -1, -1, 114, 115, 116, 117, 118, - -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, -1, -1, 85, 86, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, - -1, -1, 104, 10, 11, 12, 13, -1, -1, -1, - -1, -1, -1, 115, 116, 117, 118, -1, 25, 26, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, + 4, 5, 6, 104, 8, 9, 10, 11, 12, 13, + -1, -1, -1, 114, 115, 116, 117, 118, -1, -1, + -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, -1, + -1, 85, 86, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, + 104, 8, 9, 10, 11, 12, 13, -1, -1, -1, + -1, 115, 116, 117, 118, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, - 47, 48, 49, 50, -1, -1, -1, 54, 55, -1, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, -1, 72, 73, 74, -1, 76, + 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, -1, -1, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, @@ -1396,7 +1401,7 @@ static const yytype_int16 yycheck[] = 6, 104, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, 115, 116, 117, 118, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, @@ -1405,7 +1410,7 @@ static const yytype_int16 yycheck[] = 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, -1, 77, -1, -1, -1, @@ -1413,7 +1418,7 @@ static const yytype_int16 yycheck[] = 6, -1, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, @@ -1422,14 +1427,14 @@ static const yytype_int16 yycheck[] = 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 109, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, -1, 77, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, @@ -1437,31 +1442,24 @@ static const yytype_int16 yycheck[] = 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - -1, 72, 73, 74, 75, -1, 77, 4, 5, 6, - -1, -1, -1, 10, 11, 12, 13, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, -1, -1, -1, -1, -1, 45, 46, - 47, 48, 49, 50, -1, -1, -1, 54, 55, -1, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, -1, 72, 73, 74, -1, -1, - 77, 10, 11, 12, 13, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, -1, -1, -1, -1, -1, 45, 46, 47, 48, - 49, 50, -1, -1, -1, 54, 55, -1, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, -1, 72, 73, 74, -1, 76, 77, 10, - 11, 12, 13, 82, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, -1, - -1, -1, -1, -1, 45, 46, 47, 48, 49, 50, - -1, -1, -1, 54, 55, -1, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - -1, 72, 73, 74, -1, -1, 77 + -1, 72, 73, 74, 75, -1, 77, 10, 11, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, -1, -1, -1, + -1, -1, 45, 46, 47, 48, 49, 50, -1, -1, + -1, 54, 55, -1, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, -1, 72, + 73, 74, -1, 76, 77, 10, 11, 12, 13, 82, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, -1, -1, -1, -1, -1, + 45, 46, 47, 48, 49, 50, -1, -1, -1, 54, + 55, -1, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, + -1, -1, 77 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1470,46 +1468,45 @@ static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, - 77, 160, 161, 162, 163, 164, 169, 170, 171, 172, - 174, 175, 176, 177, 178, 181, 182, 183, 218, 219, - 220, 44, 76, 172, 175, 177, 40, 41, 76, 77, - 108, 129, 104, 114, 221, 105, 111, 9, 40, 41, - 42, 166, 167, 173, 111, 114, 76, 129, 175, 76, - 114, 159, 176, 181, 175, 106, 0, 219, 175, 181, - 185, 108, 76, 179, 180, 108, 201, 166, 165, 168, - 176, 167, 129, 104, 106, 113, 108, 3, 174, 176, - 186, 187, 76, 78, 79, 80, 81, 82, 85, 86, - 104, 107, 115, 116, 117, 118, 130, 131, 132, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 158, 181, 114, 186, 184, 113, 105, 111, 14, 15, - 16, 18, 19, 20, 21, 22, 23, 24, 56, 108, - 109, 114, 141, 154, 155, 157, 160, 161, 181, 191, - 192, 193, 194, 202, 203, 204, 206, 208, 210, 217, - 129, 165, 168, 106, 113, 107, 158, 155, 190, 176, - 129, 188, 189, 109, 187, 141, 141, 157, 85, 86, - 106, 110, 105, 105, 111, 55, 155, 104, 141, 119, - 120, 121, 116, 118, 83, 84, 87, 88, 122, 123, - 89, 90, 126, 125, 124, 91, 93, 92, 127, 107, - 109, 186, 79, 80, 180, 114, 114, 212, 104, 104, - 114, 114, 157, 104, 158, 112, 104, 109, 195, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 113, - 156, 111, 114, 109, 192, 106, 107, 158, 190, 113, - 107, 188, 106, 111, 114, 76, 114, 105, 133, 157, - 76, 82, 136, 155, 141, 141, 141, 143, 143, 144, - 144, 145, 145, 145, 145, 146, 146, 147, 148, 149, - 150, 151, 152, 157, 109, 198, 199, 200, 213, 157, - 114, 157, 112, 211, 202, 155, 155, 158, 113, 107, - 190, 113, 114, 158, 189, 106, 114, 107, 112, 56, - 201, 193, 191, 203, 214, 105, 105, 157, 171, 174, - 209, 196, 107, 190, 113, 190, 107, 158, 155, 104, - 209, 215, 216, 198, 205, 207, 129, 105, 109, 190, - 107, 157, 114, 105, 17, 194, 113, 193, 197, 201, - 114, 105, 157, 197, 198, 190, 114 + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, + 75, 77, 160, 161, 162, 163, 164, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 181, 182, + 183, 218, 219, 220, 177, 76, 77, 108, 129, 104, + 114, 221, 105, 111, 165, 166, 167, 172, 176, 111, + 114, 76, 129, 76, 114, 159, 174, 176, 106, 0, + 219, 181, 185, 108, 76, 179, 180, 108, 201, 166, + 165, 167, 129, 129, 104, 106, 113, 108, 114, 172, + 176, 186, 187, 76, 78, 79, 80, 81, 82, 85, + 86, 104, 107, 115, 116, 117, 118, 130, 131, 132, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, + 154, 158, 181, 114, 186, 184, 113, 105, 111, 14, + 15, 16, 18, 19, 20, 21, 22, 23, 24, 56, + 108, 109, 114, 141, 154, 155, 157, 160, 161, 181, + 191, 192, 193, 194, 202, 203, 204, 206, 208, 210, + 217, 106, 106, 113, 107, 158, 155, 190, 176, 129, + 188, 189, 109, 187, 141, 141, 157, 85, 86, 106, + 110, 105, 105, 111, 55, 155, 104, 141, 119, 120, + 121, 116, 118, 83, 84, 87, 88, 122, 123, 89, + 90, 126, 125, 124, 91, 93, 92, 127, 107, 109, + 186, 79, 80, 180, 114, 114, 212, 104, 104, 114, + 114, 157, 104, 158, 112, 104, 109, 195, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 113, 156, + 111, 114, 109, 192, 158, 107, 158, 190, 113, 107, + 188, 106, 111, 114, 76, 114, 105, 133, 157, 76, + 82, 136, 155, 141, 141, 141, 143, 143, 144, 144, + 145, 145, 145, 145, 146, 146, 147, 148, 149, 150, + 151, 152, 157, 109, 198, 199, 200, 213, 157, 114, + 157, 112, 211, 202, 155, 155, 107, 113, 107, 190, + 113, 114, 158, 189, 106, 114, 107, 112, 56, 201, + 193, 191, 203, 214, 105, 105, 157, 170, 172, 209, + 196, 190, 113, 190, 107, 158, 155, 104, 209, 215, + 216, 198, 205, 207, 129, 105, 109, 190, 107, 157, + 114, 105, 17, 194, 113, 193, 197, 201, 114, 105, + 157, 197, 198, 190, 114 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -1524,25 +1521,24 @@ static const yytype_uint8 yyr1[] = 149, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 157, 157, 158, 159, 160, 160, - 160, 160, 160, 160, 160, 161, 162, 162, 163, 163, - 164, 165, 165, 166, 166, 166, 166, 167, 167, 167, - 167, 168, 169, 169, 169, 169, 169, 169, 170, 170, - 170, 170, 170, 170, 170, 171, 171, 172, 172, 173, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 175, 175, 175, 175, 175, 175, 176, 176, 177, 177, - 177, 178, 179, 179, 180, 180, 180, 181, 181, 181, + 160, 160, 160, 160, 160, 160, 161, 162, 162, 163, + 163, 164, 165, 165, 166, 166, 166, 166, 167, 168, + 168, 168, 168, 168, 168, 169, 169, 169, 169, 169, + 169, 170, 170, 171, 171, 172, 172, 173, 174, 174, + 174, 174, 174, 175, 175, 175, 175, 175, 175, 175, + 175, 176, 177, 177, 177, 178, 179, 179, 180, 180, + 180, 181, 181, 181, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, - 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, - 182, 182, 182, 182, 182, 184, 183, 185, 183, 186, - 186, 187, 187, 188, 188, 189, 189, 190, 191, 192, - 192, 193, 193, 193, 193, 193, 193, 193, 194, 195, - 196, 194, 197, 197, 199, 198, 200, 198, 201, 201, - 202, 202, 203, 203, 204, 205, 205, 207, 206, 208, - 208, 209, 209, 211, 210, 212, 210, 213, 210, 214, - 214, 215, 215, 216, 216, 217, 217, 217, 217, 217, - 218, 218, 219, 219, 221, 220 + 182, 182, 182, 182, 182, 182, 182, 182, 182, 184, + 183, 185, 183, 186, 186, 187, 187, 188, 188, 189, + 189, 190, 191, 192, 192, 193, 193, 193, 193, 193, + 193, 193, 194, 195, 196, 194, 197, 197, 199, 198, + 200, 198, 201, 201, 202, 202, 203, 203, 204, 205, + 205, 207, 206, 208, 208, 209, 209, 211, 210, 212, + 210, 213, 210, 214, 214, 215, 215, 216, 216, 217, + 217, 217, 217, 217, 218, 218, 219, 219, 221, 220 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1557,25 +1553,24 @@ static const yytype_uint8 yyr2[] = 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 5, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 2, 2, - 4, 5, 6, 9, 2, 2, 1, 1, 2, 3, - 3, 2, 5, 3, 2, 3, 2, 0, 1, 1, - 1, 1, 1, 3, 6, 7, 8, 5, 1, 2, - 5, 6, 7, 4, 2, 1, 2, 1, 1, 1, - 1, 1, 2, 1, 2, 1, 1, 2, 2, 3, - 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, - 1, 4, 1, 3, 1, 3, 3, 1, 3, 4, + 4, 5, 6, 9, 2, 3, 2, 1, 1, 2, + 3, 3, 2, 5, 2, 1, 2, 1, 1, 1, + 3, 6, 7, 8, 5, 1, 2, 5, 6, 7, + 4, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 4, 1, 3, 1, 3, + 3, 1, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 6, 0, 5, 1, - 2, 3, 4, 1, 3, 1, 4, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, - 0, 5, 1, 1, 0, 2, 0, 2, 2, 3, - 1, 2, 1, 2, 5, 3, 1, 0, 6, 3, - 2, 1, 4, 0, 6, 0, 8, 0, 7, 1, - 1, 1, 0, 2, 3, 2, 2, 2, 3, 2, - 1, 2, 1, 1, 0, 3 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 6, 0, 5, 1, 2, 3, 4, 1, 3, 1, + 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 0, 0, 5, 1, 1, 0, 2, + 0, 2, 2, 3, 1, 2, 1, 2, 5, 3, + 1, 0, 6, 3, 2, 1, 4, 0, 6, 0, + 8, 0, 7, 1, 1, 1, 0, 2, 3, 2, + 2, 2, 3, 2, 1, 2, 1, 1, 0, 3 }; @@ -2473,8 +2468,7 @@ yyreduce: case 17: { - if (context->integerErrorCheck((yyvsp[0].interm.intermTypedNode), "[]")) - context->recover(); + context->checkIsScalarInteger((yyvsp[0].interm.intermTypedNode), "[]"); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } @@ -2505,7 +2499,7 @@ yyreduce: case 20: { - ES3_ONLY("", (yylsp[0]), "methods"); + ES3_OR_NEWER("", (yylsp[0]), "methods"); (yyval.interm) = (yyvsp[0].interm); (yyval.interm).nodePair.node2 = (yyvsp[-2].interm.intermTypedNode); } @@ -2552,7 +2546,7 @@ yyreduce: const TType *type = new TType((yyvsp[0].interm.intermTypedNode)->getType()); (yyvsp[-1].interm.function)->addParameter(TConstParameter(type)); (yyval.interm).function = (yyvsp[-1].interm.function); - (yyval.interm).nodePair.node1 = context->intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode), (yylsp[0])); + (yyval.interm).nodePair.node1 = TIntermediate::MakeAggregate((yyvsp[0].interm.intermTypedNode), (yylsp[0])); } break; @@ -2580,7 +2574,7 @@ yyreduce: { if ((yyvsp[0].interm.type).array) { - ES3_ONLY("[]", (yylsp[0]), "array constructor"); + ES3_OR_NEWER("[]", (yylsp[0]), "array constructor"); } (yyval.interm.function) = context->addConstructorFunc((yyvsp[0].interm.type)); } @@ -2590,8 +2584,7 @@ yyreduce: case 29: { - if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string)) - context->recover(); + context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string); const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction((yyvsp[0].lex).string, type); (yyval.interm.function) = function; @@ -2602,8 +2595,7 @@ yyreduce: case 30: { - if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string)) - context->recover(); + context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string); const TType *type = TCache::getType(EbtVoid, EbpUndefined); TFunction *function = new TFunction((yyvsp[0].lex).string, type); (yyval.interm.function) = function; @@ -2667,7 +2659,7 @@ yyreduce: case 38: { - ES3_ONLY("~", (yyloc), "bit-wise operator"); + ES3_OR_NEWER("~", (yyloc), "bit-wise operator"); (yyval.interm).op = EOpBitwiseNot; } @@ -2698,7 +2690,7 @@ yyreduce: case 42: { - ES3_ONLY("%", (yylsp[-1]), "integer modulus operator"); + ES3_OR_NEWER("%", (yylsp[-1]), "integer modulus operator"); (yyval.interm.intermTypedNode) = context->addBinaryMath(EOpIMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2735,7 +2727,7 @@ yyreduce: case 47: { - ES3_ONLY("<<", (yylsp[-1]), "bit-wise operator"); + ES3_OR_NEWER("<<", (yylsp[-1]), "bit-wise operator"); (yyval.interm.intermTypedNode) = context->addBinaryMath(EOpBitShiftLeft, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2744,7 +2736,7 @@ yyreduce: case 48: { - ES3_ONLY(">>", (yylsp[-1]), "bit-wise operator"); + ES3_OR_NEWER(">>", (yylsp[-1]), "bit-wise operator"); (yyval.interm.intermTypedNode) = context->addBinaryMath(EOpBitShiftRight, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2819,7 +2811,7 @@ yyreduce: case 58: { - ES3_ONLY("&", (yylsp[-1]), "bit-wise operator"); + ES3_OR_NEWER("&", (yylsp[-1]), "bit-wise operator"); (yyval.interm.intermTypedNode) = context->addBinaryMath(EOpBitwiseAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2834,7 +2826,7 @@ yyreduce: case 60: { - ES3_ONLY("^", (yylsp[-1]), "bit-wise operator"); + ES3_OR_NEWER("^", (yylsp[-1]), "bit-wise operator"); (yyval.interm.intermTypedNode) = context->addBinaryMath(EOpBitwiseXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2849,7 +2841,7 @@ yyreduce: case 62: { - ES3_ONLY("|", (yylsp[-1]), "bit-wise operator"); + ES3_OR_NEWER("|", (yylsp[-1]), "bit-wise operator"); (yyval.interm.intermTypedNode) = context->addBinaryMath(EOpBitwiseOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2920,8 +2912,7 @@ yyreduce: case 72: { - if (context->lValueErrorCheck((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode))) - context->recover(); + context->checkCanBeLValue((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = context->addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); } @@ -2948,7 +2939,7 @@ yyreduce: case 76: { - ES3_ONLY("%=", (yyloc), "integer modulus operator"); + ES3_OR_NEWER("%=", (yyloc), "integer modulus operator"); (yyval.interm).op = EOpIModAssign; } @@ -2969,7 +2960,7 @@ yyreduce: case 79: { - ES3_ONLY("<<=", (yyloc), "bit-wise operator"); + ES3_OR_NEWER("<<=", (yyloc), "bit-wise operator"); (yyval.interm).op = EOpBitShiftLeftAssign; } @@ -2978,7 +2969,7 @@ yyreduce: case 80: { - ES3_ONLY(">>=", (yyloc), "bit-wise operator"); + ES3_OR_NEWER(">>=", (yyloc), "bit-wise operator"); (yyval.interm).op = EOpBitShiftRightAssign; } @@ -2987,7 +2978,7 @@ yyreduce: case 81: { - ES3_ONLY("&=", (yyloc), "bit-wise operator"); + ES3_OR_NEWER("&=", (yyloc), "bit-wise operator"); (yyval.interm).op = EOpBitwiseAndAssign; } @@ -2996,7 +2987,7 @@ yyreduce: case 82: { - ES3_ONLY("^=", (yyloc), "bit-wise operator"); + ES3_OR_NEWER("^=", (yyloc), "bit-wise operator"); (yyval.interm).op = EOpBitwiseXorAssign; } @@ -3005,7 +2996,7 @@ yyreduce: case 83: { - ES3_ONLY("|=", (yyloc), "bit-wise operator"); + ES3_OR_NEWER("|=", (yyloc), "bit-wise operator"); (yyval.interm).op = EOpBitwiseOrAssign; } @@ -3030,8 +3021,7 @@ yyreduce: case 86: { - if (context->constErrorCheck((yyvsp[0].interm.intermTypedNode))) - context->recover(); + context->checkIsConst((yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } @@ -3040,8 +3030,7 @@ yyreduce: case 87: { - if (context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string)) - context->recover(); + context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string); (yyval.lex) = (yyvsp[-1].lex); } @@ -3071,11 +3060,9 @@ yyreduce: { if (((yyvsp[-2].interm.precision) == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { context->error((yylsp[-3]), "precision is not supported in fragment shader", "highp"); - context->recover(); } if (!context->symbolTable.setDefaultPrecision( (yyvsp[-1].interm.type), (yyvsp[-2].interm.precision) )) { - context->error((yylsp[-3]), "illegal type argument for default precision qualifier", getBasicString((yyvsp[-1].interm.type).type)); - context->recover(); + context->error((yylsp[-3]), "illegal type argument for default precision qualifier", getBasicString((yyvsp[-1].interm.type).getBasicType())); } (yyval.interm.intermNode) = 0; } @@ -3085,8 +3072,8 @@ yyreduce: case 91: { - ES3_ONLY(getQualifierString((yyvsp[-4].interm.type).qualifier), (yylsp[-4]), "interface blocks"); - (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[-4].interm.type), (yylsp[-3]), *(yyvsp[-3].lex).string, (yyvsp[-2].interm.fieldList), NULL, (yyloc), NULL, (yyloc)); + ES3_OR_NEWER((yyvsp[-3].lex).string->c_str(), (yylsp[-4]), "interface blocks"); + (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-4].interm.typeQualifierBuilder), (yylsp[-3]), *(yyvsp[-3].lex).string, (yyvsp[-2].interm.fieldList), NULL, (yyloc), NULL, (yyloc)); } break; @@ -3094,8 +3081,8 @@ yyreduce: case 92: { - ES3_ONLY(getQualifierString((yyvsp[-5].interm.type).qualifier), (yylsp[-5]), "interface blocks"); - (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[-5].interm.type), (yylsp[-4]), *(yyvsp[-4].lex).string, (yyvsp[-3].interm.fieldList), (yyvsp[-1].lex).string, (yylsp[-1]), NULL, (yyloc)); + ES3_OR_NEWER((yyvsp[-4].lex).string->c_str(), (yylsp[-5]), "interface blocks"); + (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-5].interm.typeQualifierBuilder), (yylsp[-4]), *(yyvsp[-4].lex).string, (yyvsp[-3].interm.fieldList), (yyvsp[-1].lex).string, (yylsp[-1]), NULL, (yyloc)); } break; @@ -3103,8 +3090,8 @@ yyreduce: case 93: { - ES3_ONLY(getQualifierString((yyvsp[-8].interm.type).qualifier), (yylsp[-8]), "interface blocks"); - (yyval.interm.intermNode) = context->addInterfaceBlock((yyvsp[-8].interm.type), (yylsp[-7]), *(yyvsp[-7].lex).string, (yyvsp[-6].interm.fieldList), (yyvsp[-4].lex).string, (yylsp[-4]), (yyvsp[-2].interm.intermTypedNode), (yylsp[-3])); + ES3_OR_NEWER((yyvsp[-7].lex).string->c_str(), (yylsp[-8]), "interface blocks"); + (yyval.interm.intermNode) = context->addInterfaceBlock(*(yyvsp[-8].interm.typeQualifierBuilder), (yylsp[-7]), *(yyvsp[-7].lex).string, (yyvsp[-6].interm.fieldList), (yyvsp[-4].lex).string, (yylsp[-4]), (yyvsp[-2].interm.intermTypedNode), (yylsp[-3])); } break; @@ -3112,7 +3099,7 @@ yyreduce: case 94: { - context->parseGlobalLayoutQualifier((yyvsp[-1].interm.type)); + context->parseGlobalLayoutQualifier(*(yyvsp[-1].interm.typeQualifierBuilder)); (yyval.interm.intermNode) = 0; } @@ -3121,7 +3108,7 @@ yyreduce: case 95: { - (yyval.interm).function = context->parseFunctionDeclarator((yylsp[0]), (yyvsp[-1].interm.function)); + (yyval.interm.intermNode) = context->parseInvariantDeclaration(*(yyvsp[-2].interm.typeQualifierBuilder), (yylsp[-1]), (yyvsp[-1].lex).string, (yyvsp[-1].lex).symbol); } break; @@ -3129,7 +3116,8 @@ yyreduce: case 96: { - (yyval.interm.function) = (yyvsp[0].interm.function); + (yyval.interm).function = context->parseFunctionDeclarator((yylsp[0]), (yyvsp[-1].interm.function)); + context->exitFunctionDeclaration(); } break; @@ -3145,6 +3133,14 @@ yyreduce: case 98: { + (yyval.interm.function) = (yyvsp[0].interm.function); + } + + break; + + case 99: + + { // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) @@ -3155,7 +3151,7 @@ yyreduce: break; - case 99: + case 100: { // @@ -3167,7 +3163,6 @@ yyreduce: // This parameter > first is void // context->error((yylsp[-1]), "cannot be an argument type except for '(void)'", "void"); - context->recover(); delete (yyvsp[0].interm).param.type; } else { // Add the parameter @@ -3178,44 +3173,40 @@ yyreduce: break; - case 100: + case 101: { (yyval.interm.function) = context->parseFunctionHeader((yyvsp[-2].interm.type), (yyvsp[-1].lex).string, (yylsp[-1])); context->symbolTable.push(); + context->enterFunctionDeclaration(); } break; - case 101: + case 102: { - if ((yyvsp[-1].interm.type).type == EbtVoid) { + if ((yyvsp[-1].interm.type).getBasicType() == EbtVoid) { context->error((yylsp[0]), "illegal use of type 'void'", (yyvsp[0].lex).string->c_str()); - context->recover(); } - if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string)) - context->recover(); + context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string); TParameter param = {(yyvsp[0].lex).string, new TType((yyvsp[-1].interm.type))}; (yyval.interm).param = param; } break; - case 102: + case 103: { // Check that we can make an array out of this type - if (context->arrayTypeErrorCheck((yylsp[-2]), (yyvsp[-4].interm.type))) - context->recover(); + context->checkIsValidTypeForArray((yylsp[-2]), (yyvsp[-4].interm.type)); + + context->checkIsNotReserved((yylsp[-3]), *(yyvsp[-3].lex).string); - if (context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string)) - context->recover(); + unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode)); - int size; - if (context->arraySizeErrorCheck((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), size)) - context->recover(); (yyvsp[-4].interm.type).setArraySize(size); TType* type = new TType((yyvsp[-4].interm.type)); @@ -3225,24 +3216,11 @@ yyreduce: break; - case 103: - - { - (yyval.interm) = (yyvsp[0].interm); - if (context->paramErrorCheck((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type)) - context->recover(); - } - - break; - case 104: { (yyval.interm) = (yyvsp[0].interm); - if (context->parameterSamplerErrorCheck((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type)) - context->recover(); - if (context->paramErrorCheck((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type)) - context->recover(); + context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm).param.type); } break; @@ -3251,8 +3229,7 @@ yyreduce: { (yyval.interm) = (yyvsp[0].interm); - if (context->paramErrorCheck((yylsp[0]), (yyvsp[-2].interm.qualifier), (yyvsp[-1].interm.qualifier), (yyval.interm).param.type)) - context->recover(); + (yyval.interm).param.type->setQualifier(EvqIn); } break; @@ -3261,10 +3238,7 @@ yyreduce: { (yyval.interm) = (yyvsp[0].interm); - if (context->parameterSamplerErrorCheck((yylsp[0]), (yyvsp[-1].interm.qualifier), *(yyvsp[0].interm).param.type)) - context->recover(); - if (context->paramErrorCheck((yylsp[0]), EvqTemporary, (yyvsp[-1].interm.qualifier), (yyval.interm).param.type)) - context->recover(); + context->checkIsParameterQualifierValid((yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm).param.type); } break; @@ -3272,7 +3246,8 @@ yyreduce: case 107: { - (yyval.interm.qualifier) = EvqIn; + (yyval.interm) = (yyvsp[0].interm); + (yyval.interm).param.type->setQualifier(EvqIn); } break; @@ -3280,7 +3255,8 @@ yyreduce: case 108: { - (yyval.interm.qualifier) = EvqIn; + TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; + (yyval.interm).param = param; } break; @@ -3288,7 +3264,7 @@ yyreduce: case 109: { - (yyval.interm.qualifier) = EvqOut; + (yyval.interm) = (yyvsp[0].interm); } break; @@ -3296,7 +3272,8 @@ yyreduce: case 110: { - (yyval.interm.qualifier) = EvqInOut; + (yyval.interm) = (yyvsp[-2].interm); + (yyval.interm).intermAggregate = context->parseDeclarator((yyval.interm).type, (yyvsp[-2].interm).intermAggregate, (yylsp[0]), *(yyvsp[0].lex).string); } break; @@ -3304,8 +3281,8 @@ yyreduce: case 111: { - TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; - (yyval.interm).param = param; + (yyval.interm) = (yyvsp[-5].interm); + (yyval.interm).intermAggregate = context->parseArrayDeclarator((yyval.interm).type, (yyvsp[-5].interm).intermAggregate, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode)); } break; @@ -3313,7 +3290,9 @@ yyreduce: case 112: { - (yyval.interm) = (yyvsp[0].interm); + ES3_OR_NEWER("[]", (yylsp[-4]), "implicitly sized array"); + (yyval.interm) = (yyvsp[-6].interm); + (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-6].interm).intermAggregate, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); } break; @@ -3321,8 +3300,9 @@ yyreduce: case 113: { - (yyval.interm) = (yyvsp[-2].interm); - (yyval.interm).intermAggregate = context->parseDeclarator((yyval.interm).type, (yyvsp[-2].interm).intermAggregate, (yylsp[0]), *(yyvsp[0].lex).string); + ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)"); + (yyval.interm) = (yyvsp[-7].interm); + (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-7].interm).intermAggregate, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); } break; @@ -3330,8 +3310,8 @@ yyreduce: case 114: { - (yyval.interm) = (yyvsp[-5].interm); - (yyval.interm).intermAggregate = context->parseArrayDeclarator((yyval.interm).type, (yyvsp[-5].interm).intermAggregate, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode)); + (yyval.interm) = (yyvsp[-4].interm); + (yyval.interm).intermAggregate = context->parseInitDeclarator((yyval.interm).type, (yyvsp[-4].interm).intermAggregate, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); } break; @@ -3339,9 +3319,8 @@ yyreduce: case 115: { - ES3_ONLY("[]", (yylsp[-4]), "implicitly sized array"); - (yyval.interm) = (yyvsp[-6].interm); - (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-6].interm).intermAggregate, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).type = (yyvsp[0].interm.type); + (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), ""); } break; @@ -3349,9 +3328,8 @@ yyreduce: case 116: { - ES3_ONLY("=", (yylsp[-1]), "first-class arrays (array initializer)"); - (yyval.interm) = (yyvsp[-7].interm); - (yyval.interm).intermAggregate = context->parseArrayInitDeclarator((yyval.interm).type, (yyvsp[-7].interm).intermAggregate, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).type = (yyvsp[-1].interm.type); + (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string); } break; @@ -3359,8 +3337,8 @@ yyreduce: case 117: { - (yyval.interm) = (yyvsp[-4].interm); - (yyval.interm).intermAggregate = context->parseInitDeclarator((yyval.interm).type, (yyvsp[-4].interm).intermAggregate, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).type = (yyvsp[-4].interm.type); + (yyval.interm).intermAggregate = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode)); } break; @@ -3368,8 +3346,9 @@ yyreduce: case 118: { - (yyval.interm).type = (yyvsp[0].interm.type); - (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), ""); + ES3_OR_NEWER("[]", (yylsp[-3]), "implicitly sized array"); + (yyval.interm).type = (yyvsp[-5].interm.type); + (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); } break; @@ -3377,8 +3356,9 @@ yyreduce: case 119: { - (yyval.interm).type = (yyvsp[-1].interm.type); - (yyval.interm).intermAggregate = context->parseSingleDeclaration((yyval.interm).type, (yylsp[0]), *(yyvsp[0].lex).string); + ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)"); + (yyval.interm).type = (yyvsp[-6].interm.type); + (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); } break; @@ -3386,8 +3366,8 @@ yyreduce: case 120: { - (yyval.interm).type = (yyvsp[-4].interm.type); - (yyval.interm).intermAggregate = context->parseSingleArrayDeclaration((yyval.interm).type, (yylsp[-3]), *(yyvsp[-3].lex).string, (yylsp[-2]), (yyvsp[-1].interm.intermTypedNode)); + (yyval.interm).type = (yyvsp[-3].interm.type); + (yyval.interm).intermAggregate = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); } break; @@ -3395,9 +3375,14 @@ yyreduce: case 121: { - ES3_ONLY("[]", (yylsp[-3]), "implicitly sized array"); - (yyval.interm).type = (yyvsp[-5].interm.type); - (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-4]), *(yyvsp[-4].lex).string, (yylsp[-3]), nullptr, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.type) = (yyvsp[0].interm.type); + + if ((yyvsp[0].interm.type).array) { + ES3_OR_NEWER("[]", (yylsp[0]), "first-class-array"); + if (context->getShaderVersion() != 300) { + (yyvsp[0].interm.type).clearArrayness(); + } + } } break; @@ -3405,9 +3390,7 @@ yyreduce: case 122: { - ES3_ONLY("=", (yylsp[-1]), "first-class arrays (array initializer)"); - (yyval.interm).type = (yyvsp[-6].interm.type); - (yyval.interm).intermAggregate = context->parseSingleArrayInitDeclaration((yyval.interm).type, (yylsp[-5]), *(yyvsp[-5].lex).string, (yylsp[-4]), (yyvsp[-3].interm.intermTypedNode), (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.type) = context->addFullySpecifiedType(*(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.type)); } break; @@ -3415,8 +3398,7 @@ yyreduce: case 123: { - (yyval.interm).type = (yyvsp[-3].interm.type); - (yyval.interm).intermAggregate = context->parseSingleInitDeclaration((yyval.interm).type, (yylsp[-2]), *(yyvsp[-2].lex).string, (yylsp[-1]), (yyvsp[0].interm.intermTypedNode)); + (yyval.interm.qualifier) = EvqSmooth; } break; @@ -3424,8 +3406,7 @@ yyreduce: case 124: { - // $$.type is not used in invariant declarations. - (yyval.interm).intermAggregate = context->parseInvariantDeclaration((yylsp[-1]), (yylsp[0]), (yyvsp[0].lex).string, (yyvsp[0].lex).symbol); + (yyval.interm.qualifier) = EvqFlat; } break; @@ -3433,14 +3414,8 @@ yyreduce: case 125: { - (yyval.interm.type) = (yyvsp[0].interm.type); - - if ((yyvsp[0].interm.type).array) { - ES3_ONLY("[]", (yylsp[0]), "first-class-array"); - if (context->getShaderVersion() != 300) { - (yyvsp[0].interm.type).clearArrayness(); - } - } + (yyval.interm.typeQualifierBuilder) = context->createTypeQualifierBuilder((yylsp[0])); + (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper)); } break; @@ -3448,7 +3423,8 @@ yyreduce: case 126: { - (yyval.interm.type) = context->addFullySpecifiedType((yyvsp[-1].interm.type).qualifier, (yyvsp[-1].interm.type).invariant, (yyvsp[-1].interm.type).layoutQualifier, (yyvsp[0].interm.type)); + (yyval.interm.typeQualifierBuilder) = (yyvsp[-1].interm.typeQualifierBuilder); + (yyval.interm.typeQualifierBuilder)->appendQualifier((yyvsp[0].interm.qualifierWrapper)); } break; @@ -3456,7 +3432,7 @@ yyreduce: case 127: { - (yyval.interm.type).qualifier = EvqSmooth; + // empty } break; @@ -3464,7 +3440,11 @@ yyreduce: case 128: { - (yyval.interm.type).qualifier = EvqFlat; + if (!context->declaringFunction() && (yyvsp[0].interm.qualifier) != EvqConst && !context->symbolTable.atGlobalLevel()) + { + context->error((yylsp[0]), "Local variables can only use the const storage qualifier.", getQualifierString((yyvsp[0].interm.qualifier))); + } + (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper((yyvsp[0].interm.qualifier), (yylsp[0])); } break; @@ -3472,7 +3452,8 @@ yyreduce: case 129: { - (yyval.interm.qualifier) = EvqConst; + context->checkIsAtGlobalLevel((yylsp[0]), "layout"); + (yyval.interm.qualifierWrapper) = new TLayoutQualifierWrapper((yyvsp[0].interm.layoutQualifier), (yylsp[0])); } break; @@ -3480,11 +3461,7 @@ yyreduce: case 130: { - VERTEX_ONLY("attribute", (yylsp[0])); - ES2_ONLY("attribute", (yylsp[0])); - if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "attribute")) - context->recover(); - (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yylsp[0])); + (yyval.interm.qualifierWrapper) = new TPrecisionQualifierWrapper((yyvsp[0].interm.precision), (yylsp[0])); } break; @@ -3492,13 +3469,7 @@ yyreduce: case 131: { - ES2_ONLY("varying", (yylsp[0])); - if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "varying")) - context->recover(); - if (context->getShaderType() == GL_VERTEX_SHADER) - (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[0])); - else - (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[0])); + (yyval.interm.qualifierWrapper) = new TInterpolationQualifierWrapper((yyvsp[0].interm.qualifier), (yylsp[0])); } break; @@ -3506,14 +3477,8 @@ yyreduce: case 132: { - ES2_ONLY("varying", (yylsp[-1])); - if (context->globalErrorCheck((yylsp[-1]), context->symbolTable.atGlobalLevel(), "invariant varying")) - context->recover(); - if (context->getShaderType() == GL_VERTEX_SHADER) - (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[-1])); - else - (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[-1])); - (yyval.interm.type).invariant = true; + context->checkIsAtGlobalLevel((yylsp[0]), "invariant"); + (yyval.interm.qualifierWrapper) = new TInvariantQualifierWrapper((yylsp[0])); } break; @@ -3521,12 +3486,10 @@ yyreduce: case 133: { - if ((yyvsp[0].interm.type).qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) - { - context->error((yylsp[0]), "Local variables can only use the const storage qualifier.", getQualifierString((yyvsp[0].interm.type).qualifier)); - context->recover(); - } - (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0])); + VERTEX_ONLY("attribute", (yylsp[0])); + ES2_ONLY("attribute", (yylsp[0])); + context->checkIsAtGlobalLevel((yylsp[0]), "attribute"); + (yyval.interm.qualifier) = EvqAttribute; } break; @@ -3534,7 +3497,12 @@ yyreduce: case 134: { - (yyval.interm.type) = context->joinInterpolationQualifiers((yylsp[-1]), (yyvsp[-1].interm.type).qualifier, (yylsp[0]), (yyvsp[0].interm.type).qualifier); + ES2_ONLY("varying", (yylsp[0])); + context->checkIsAtGlobalLevel((yylsp[0]), "varying"); + if (context->getShaderType() == GL_VERTEX_SHADER) + (yyval.interm.qualifier) = EvqVaryingOut; + else + (yyval.interm.qualifier) = EvqVaryingIn; } break; @@ -3542,11 +3510,7 @@ yyreduce: case 135: { - context->error((yylsp[0]), "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString((yyvsp[0].interm.type).qualifier)); - context->recover(); - - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[0])); + (yyval.interm.qualifier) = EvqConst; } break; @@ -3554,8 +3518,24 @@ yyreduce: case 136: { - (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).layoutQualifier = (yyvsp[0].interm.layoutQualifier); + if (context->declaringFunction()) + { + (yyval.interm.qualifier) = EvqIn; + } + else if (context->getShaderType() == GL_FRAGMENT_SHADER) + { + ES3_OR_NEWER("in", (yylsp[0]), "storage qualifier"); + (yyval.interm.qualifier) = EvqFragmentIn; + } + else if (context->getShaderType() == GL_VERTEX_SHADER) + { + ES3_OR_NEWER("in", (yylsp[0]), "storage qualifier"); + (yyval.interm.qualifier) = EvqVertexIn; + } + else + { + (yyval.interm.qualifier) = EvqComputeIn; + } } break; @@ -3563,8 +3543,23 @@ yyreduce: case 137: { - (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0])); - (yyval.interm.type).layoutQualifier = (yyvsp[-1].interm.layoutQualifier); + if (context->declaringFunction()) + { + (yyval.interm.qualifier) = EvqOut; + } + else + { + ES3_OR_NEWER("out", (yylsp[0]), "storage qualifier"); + NON_COMPUTE_ONLY("out", (yylsp[0])); + if (context->getShaderType() == GL_FRAGMENT_SHADER) + { + (yyval.interm.qualifier) = EvqFragmentOut; + } + else + { + (yyval.interm.qualifier) = EvqVertexOut; + } + } } break; @@ -3572,9 +3567,11 @@ yyreduce: case 138: { - context->es3InvariantErrorCheck((yyvsp[0].interm.type).qualifier, (yylsp[-1])); - (yyval.interm.type).setBasic(EbtVoid, (yyvsp[0].interm.type).qualifier, (yylsp[0])); - (yyval.interm.type).invariant = true; + if (!context->declaringFunction()) + { + context->error((yylsp[0]), "invalid inout qualifier", "'inout' can be only used with function parameters"); + } + (yyval.interm.qualifier) = EvqInOut; } break; @@ -3582,9 +3579,8 @@ yyreduce: case 139: { - context->es3InvariantErrorCheck((yyvsp[0].interm.type).qualifier, (yylsp[-2])); - (yyval.interm.type) = context->joinInterpolationQualifiers((yylsp[-1]), (yyvsp[-1].interm.type).qualifier, (yylsp[0]), (yyvsp[0].interm.type).qualifier); - (yyval.interm.type).invariant = true; + ES3_OR_NEWER("centroid", (yylsp[0]), "storage qualifier"); + (yyval.interm.qualifier) = EvqCentroid; } break; @@ -3592,7 +3588,8 @@ yyreduce: case 140: { - (yyval.interm.type).qualifier = EvqConst; + context->checkIsAtGlobalLevel((yylsp[0]), "uniform"); + (yyval.interm.qualifier) = EvqUniform; } break; @@ -3600,8 +3597,11 @@ yyreduce: case 141: { - ES3_ONLY("in", (yylsp[0]), "storage qualifier"); - (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + (yyval.interm.type) = (yyvsp[0].interm.type); + + if ((yyval.interm.type).precision == EbpUndefined) { + (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).getBasicType()); + } } break; @@ -3609,8 +3609,7 @@ yyreduce: case 142: { - ES3_ONLY("out", (yylsp[0]), "storage qualifier"); - (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; + (yyval.interm.precision) = EbpHigh; } break; @@ -3618,13 +3617,7 @@ yyreduce: case 143: { - ES3_ONLY("centroid in", (yylsp[-1]), "storage qualifier"); - if (context->getShaderType() == GL_VERTEX_SHADER) - { - context->error((yylsp[-1]), "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); - context->recover(); - } - (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; + (yyval.interm.precision) = EbpMedium; } break; @@ -3632,13 +3625,7 @@ yyreduce: case 144: { - ES3_ONLY("centroid out", (yylsp[-1]), "storage qualifier"); - if (context->getShaderType() == GL_FRAGMENT_SHADER) - { - context->error((yylsp[-1]), "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); - context->recover(); - } - (yyval.interm.type).qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + (yyval.interm.precision) = EbpLow; } break; @@ -3646,9 +3633,8 @@ yyreduce: case 145: { - if (context->globalErrorCheck((yylsp[0]), context->symbolTable.atGlobalLevel(), "uniform")) - context->recover(); - (yyval.interm.type).qualifier = EvqUniform; + ES3_OR_NEWER("layout", (yylsp[-3]), "qualifier"); + (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier); } break; @@ -3656,14 +3642,7 @@ yyreduce: case 146: { - (yyval.interm.type) = (yyvsp[0].interm.type); - - if ((yyval.interm.type).precision == EbpUndefined) { - (yyval.interm.type).precision = context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).type); - if (context->precisionErrorCheck((yylsp[0]), (yyval.interm.type).precision, (yyvsp[0].interm.type).type)) { - context->recover(); - } - } + (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier); } break; @@ -3671,13 +3650,7 @@ yyreduce: case 147: { - (yyval.interm.type) = (yyvsp[0].interm.type); - (yyval.interm.type).precision = (yyvsp[-1].interm.precision); - - if (!SupportsPrecision((yyvsp[0].interm.type).type)) { - context->error((yylsp[-1]), "illegal type for precision qualifier", getBasicString((yyvsp[0].interm.type).type)); - context->recover(); - } + (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier), (yylsp[0])); } break; @@ -3685,7 +3658,7 @@ yyreduce: case 148: { - (yyval.interm.precision) = EbpHigh; + (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0])); } break; @@ -3693,7 +3666,7 @@ yyreduce: case 149: { - (yyval.interm.precision) = EbpMedium; + (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0])); } break; @@ -3701,7 +3674,7 @@ yyreduce: case 150: { - (yyval.interm.precision) = EbpLow; + (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0])); } break; @@ -3709,8 +3682,7 @@ yyreduce: case 151: { - ES3_ONLY("layout", (yylsp[-3]), "qualifier"); - (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier); + (yyval.interm.type).initialize((yyvsp[0].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); } break; @@ -3718,7 +3690,9 @@ yyreduce: case 152: { - (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier); + ES3_OR_NEWER("[]", (yylsp[-1]), "implicitly sized array"); + (yyval.interm.type).initialize((yyvsp[-2].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); + (yyval.interm.type).setArraySize(0); } break; @@ -3726,7 +3700,12 @@ yyreduce: case 153: { - (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers((yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier)); + (yyval.interm.type).initialize((yyvsp[-3].interm.typeSpecifierNonArray), (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); + if (context->checkIsValidTypeForArray((yylsp[-2]), (yyval.interm.type))) + { + unsigned int size = context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode)); + (yyval.interm.type).setArraySize(size); + } } break; @@ -3734,7 +3713,7 @@ yyreduce: case 154: { - (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[0].lex).string, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtVoid, (yylsp[0])); } break; @@ -3742,7 +3721,7 @@ yyreduce: case 155: { - (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), *(yyvsp[0].lex).string, (yyvsp[0].lex).i, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); } break; @@ -3750,7 +3729,7 @@ yyreduce: case 156: { - (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(*(yyvsp[-2].lex).string, (yylsp[-2]), *(yyvsp[0].lex).string, (yyvsp[0].lex).i, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0])); } break; @@ -3758,7 +3737,7 @@ yyreduce: case 157: { - (yyval.interm.type) = (yyvsp[0].interm.type); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0])); } break; @@ -3766,9 +3745,7 @@ yyreduce: case 158: { - ES3_ONLY("[]", (yylsp[-1]), "implicitly sized array"); - (yyval.interm.type) = (yyvsp[-2].interm.type); - (yyval.interm.type).setArraySize(0); + (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0])); } break; @@ -3776,16 +3753,8 @@ yyreduce: case 159: { - (yyval.interm.type) = (yyvsp[-3].interm.type); - - if (context->arrayTypeErrorCheck((yylsp[-2]), (yyvsp[-3].interm.type))) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode), size)) - context->recover(); - (yyval.interm.type).setArraySize(size); - } + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(2); } break; @@ -3793,8 +3762,8 @@ yyreduce: case 160: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(3); } break; @@ -3802,8 +3771,8 @@ yyreduce: case 161: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(4); } break; @@ -3811,8 +3780,8 @@ yyreduce: case 162: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(2); } break; @@ -3820,8 +3789,8 @@ yyreduce: case 163: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(3); } break; @@ -3829,8 +3798,8 @@ yyreduce: case 164: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(4); } break; @@ -3838,9 +3807,8 @@ yyreduce: case 165: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(2); + (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(2); } break; @@ -3848,9 +3816,8 @@ yyreduce: case 166: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(3); + (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(3); } break; @@ -3858,9 +3825,8 @@ yyreduce: case 167: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(4); + (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(4); } break; @@ -3868,9 +3834,8 @@ yyreduce: case 168: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(2); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(2); } break; @@ -3878,9 +3843,8 @@ yyreduce: case 169: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(3); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(3); } break; @@ -3888,9 +3852,8 @@ yyreduce: case 170: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(4); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setAggregate(4); } break; @@ -3898,9 +3861,8 @@ yyreduce: case 171: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(2); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(2, 2); } break; @@ -3908,9 +3870,8 @@ yyreduce: case 172: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(3); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(3, 3); } break; @@ -3918,9 +3879,8 @@ yyreduce: case 173: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(4); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(4, 4); } break; @@ -3928,9 +3888,8 @@ yyreduce: case 174: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(2); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(2, 3); } break; @@ -3938,9 +3897,8 @@ yyreduce: case 175: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(3); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(3, 2); } break; @@ -3948,9 +3906,8 @@ yyreduce: case 176: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUInt, qual, (yylsp[0])); - (yyval.interm.type).setAggregate(4); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(2, 4); } break; @@ -3958,9 +3915,8 @@ yyreduce: case 177: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(2, 2); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(4, 2); } break; @@ -3968,9 +3924,8 @@ yyreduce: case 178: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(3, 3); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(3, 4); } break; @@ -3978,9 +3933,8 @@ yyreduce: case 179: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(4, 4); + (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).setMatrix(4, 3); } break; @@ -3988,9 +3942,7 @@ yyreduce: case 180: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(2, 3); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2D, (yylsp[0])); } break; @@ -3998,9 +3950,7 @@ yyreduce: case 181: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(3, 2); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler3D, (yylsp[0])); } break; @@ -4008,9 +3958,7 @@ yyreduce: case 182: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(2, 4); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCube, (yylsp[0])); } break; @@ -4018,9 +3966,7 @@ yyreduce: case 183: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(4, 2); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArray, (yylsp[0])); } break; @@ -4028,9 +3974,7 @@ yyreduce: case 184: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(3, 4); + (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2D, (yylsp[0])); } break; @@ -4038,9 +3982,7 @@ yyreduce: case 185: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[0])); - (yyval.interm.type).setMatrix(4, 3); + (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler3D, (yylsp[0])); } break; @@ -4048,8 +3990,7 @@ yyreduce: case 186: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSampler2D, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCube, (yylsp[0])); } break; @@ -4057,8 +3998,7 @@ yyreduce: case 187: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSampler3D, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DArray, (yylsp[0])); } break; @@ -4066,8 +4006,7 @@ yyreduce: case 188: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSamplerCube, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2D, (yylsp[0])); } break; @@ -4075,8 +4014,7 @@ yyreduce: case 189: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSampler2DArray, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler3D, (yylsp[0])); } break; @@ -4084,8 +4022,7 @@ yyreduce: case 190: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtISampler2D, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCube, (yylsp[0])); } break; @@ -4093,8 +4030,7 @@ yyreduce: case 191: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtISampler3D, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DArray, (yylsp[0])); } break; @@ -4102,8 +4038,7 @@ yyreduce: case 192: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtISamplerCube, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DShadow, (yylsp[0])); } break; @@ -4111,8 +4046,7 @@ yyreduce: case 193: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtISampler2DArray, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeShadow, (yylsp[0])); } break; @@ -4120,8 +4054,7 @@ yyreduce: case 194: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUSampler2D, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArrayShadow, (yylsp[0])); } break; @@ -4129,94 +4062,35 @@ yyreduce: case 195: { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUSampler3D, qual, (yylsp[0])); - } - - break; - - case 196: - - { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUSamplerCube, qual, (yylsp[0])); - } - - break; - - case 197: - - { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtUSampler2DArray, qual, (yylsp[0])); - } - - break; - - case 198: - - { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSampler2DShadow, qual, (yylsp[0])); - } - - break; - - case 199: - - { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSamplerCubeShadow, qual, (yylsp[0])); - } - - break; - - case 200: - - { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSampler2DArrayShadow, qual, (yylsp[0])); - } - - break; - - case 201: - - { if (!context->supportsExtension("GL_OES_EGL_image_external") && !context->supportsExtension("GL_NV_EGL_stream_consumer_external")) { context->error((yylsp[0]), "unsupported type", "samplerExternalOES"); - context->recover(); } - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSamplerExternalOES, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternalOES, (yylsp[0])); } break; - case 202: + case 196: { if (!context->supportsExtension("GL_ARB_texture_rectangle")) { context->error((yylsp[0]), "unsupported type", "sampler2DRect"); - context->recover(); } - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DRect, (yylsp[0])); } break; - case 203: + case 197: { - (yyval.interm.type) = (yyvsp[0].interm.type); - (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.typeSpecifierNonArray) = (yyvsp[0].interm.typeSpecifierNonArray); } break; - case 204: + case 198: { // @@ -4224,42 +4098,41 @@ yyreduce: // type. // TType& structure = static_cast<TVariable*>((yyvsp[0].lex).symbol)->getType(); - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - (yyval.interm.type).setBasic(EbtStruct, qual, (yylsp[0])); - (yyval.interm.type).userDef = &structure; + (yyval.interm.typeSpecifierNonArray).initialize(EbtStruct, (yylsp[0])); + (yyval.interm.typeSpecifierNonArray).userDef = &structure; } break; - case 205: + case 199: - { if (context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string)) context->recover(); } + { context->enterStructDeclaration((yylsp[-1]), *(yyvsp[-1].lex).string); } break; - case 206: + case 200: { - (yyval.interm.type) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList)); + (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-5]), (yylsp[-4]), (yyvsp[-4].lex).string, (yyvsp[-1].interm.fieldList)); } break; - case 207: + case 201: - { if (context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string)) context->recover(); } + { context->enterStructDeclaration((yylsp[0]), *(yyvsp[0].lex).string); } break; - case 208: + case 202: { - (yyval.interm.type) = context->addStructure((yylsp[-4]), (yyloc), NewPoolTString(""), (yyvsp[-1].interm.fieldList)); + (yyval.interm.typeSpecifierNonArray) = context->addStructure((yylsp[-4]), (yyloc), NewPoolTString(""), (yyvsp[-1].interm.fieldList)); } break; - case 209: + case 203: { (yyval.interm.fieldList) = (yyvsp[0].interm.fieldList); @@ -4267,7 +4140,7 @@ yyreduce: break; - case 210: + case 204: { (yyval.interm.fieldList) = (yyvsp[-1].interm.fieldList); @@ -4276,7 +4149,6 @@ yyreduce: for (size_t j = 0; j < (yyval.interm.fieldList)->size(); ++j) { if ((*(yyval.interm.fieldList))[j]->name() == field->name()) { context->error((yylsp[0]), "duplicate field name in structure:", "struct", field->name().c_str()); - context->recover(); } } (yyval.interm.fieldList)->push_back(field); @@ -4285,7 +4157,7 @@ yyreduce: break; - case 211: + case 205: { (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList)); @@ -4293,18 +4165,16 @@ yyreduce: break; - case 212: + case 206: { // ES3 Only, but errors should be handled elsewhere - (yyvsp[-2].interm.type).qualifier = (yyvsp[-3].interm.type).qualifier; - (yyvsp[-2].interm.type).layoutQualifier = (yyvsp[-3].interm.type).layoutQualifier; - (yyval.interm.fieldList) = context->addStructDeclaratorList((yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList)); + (yyval.interm.fieldList) = context->addStructDeclaratorListWithQualifiers(*(yyvsp[-3].interm.typeQualifierBuilder), &(yyvsp[-2].interm.type), (yyvsp[-1].interm.fieldList)); } break; - case 213: + case 207: { (yyval.interm.fieldList) = NewPoolTFieldList(); @@ -4313,7 +4183,7 @@ yyreduce: break; - case 214: + case 208: { (yyval.interm.fieldList)->push_back((yyvsp[0].interm.field)); @@ -4321,11 +4191,10 @@ yyreduce: break; - case 215: + case 209: { - if (context->reservedErrorCheck((yylsp[0]), *(yyvsp[0].lex).string)) - context->recover(); + context->checkIsNotReserved((yylsp[0]), *(yyvsp[0].lex).string); TType* type = new TType(EbtVoid, EbpUndefined); (yyval.interm.field) = new TField(type, (yyvsp[0].lex).string, (yylsp[0])); @@ -4333,16 +4202,13 @@ yyreduce: break; - case 216: + case 210: { - if (context->reservedErrorCheck((yylsp[-3]), *(yyvsp[-3].lex).string)) - context->recover(); + context->checkIsNotReserved((yylsp[-3]), *(yyvsp[-3].lex).string); TType* type = new TType(EbtVoid, EbpUndefined); - int size; - if (context->arraySizeErrorCheck((yylsp[-1]), (yyvsp[-1].interm.intermTypedNode), size)) - context->recover(); + unsigned int size = context->checkIsValidArraySize((yylsp[-1]), (yyvsp[-1].interm.intermTypedNode)); type->setArraySize(size); (yyval.interm.field) = new TField(type, (yyvsp[-3].lex).string, (yylsp[-3])); @@ -4350,91 +4216,91 @@ yyreduce: break; - case 217: + case 211: { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } break; - case 218: + case 212: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 219: + case 213: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); } break; - case 220: + case 214: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 221: + case 215: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 222: + case 216: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 223: + case 217: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 224: + case 218: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch); } break; - case 225: + case 219: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase); } break; - case 226: + case 220: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 227: + case 221: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 228: + case 222: { (yyval.interm.intermAggregate) = 0; } break; - case 229: + case 223: { context->symbolTable.push(); } break; - case 230: + case 224: { context->symbolTable.pop(); } break; - case 231: + case 225: { if ((yyvsp[-2].interm.intermAggregate) != 0) { @@ -4446,43 +4312,43 @@ yyreduce: break; - case 232: + case 226: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); } break; - case 233: + case 227: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 234: + case 228: { context->symbolTable.push(); } break; - case 235: + case 229: { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); } break; - case 236: + case 230: { context->symbolTable.push(); } break; - case 237: + case 231: { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } break; - case 238: + case 232: { (yyval.interm.intermAggregate) = 0; @@ -4490,7 +4356,7 @@ yyreduce: break; - case 239: + case 233: { if ((yyvsp[-1].interm.intermAggregate)) { @@ -4502,15 +4368,15 @@ yyreduce: break; - case 240: + case 234: { - (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[0].interm.intermNode), (yyloc)); + (yyval.interm.intermAggregate) = TIntermediate::MakeAggregate((yyvsp[0].interm.intermNode), (yyloc)); } break; - case 241: + case 235: { (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[-1].interm.intermAggregate), (yyvsp[0].interm.intermNode), (yyloc)); @@ -4518,29 +4384,28 @@ yyreduce: break; - case 242: + case 236: { (yyval.interm.intermNode) = 0; } break; - case 243: + case 237: { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[-1].interm.intermTypedNode)); } break; - case 244: + case 238: { - if (context->boolErrorCheck((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode))) - context->recover(); - (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4])); + context->checkIsScalarBool((yylsp[-4]), (yyvsp[-2].interm.intermTypedNode)); + (yyval.interm.intermNode) = context->intermediate.addIfElse((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yylsp[-4])); } break; - case 245: + case 239: { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); @@ -4549,7 +4414,7 @@ yyreduce: break; - case 246: + case 240: { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); @@ -4558,13 +4423,13 @@ yyreduce: break; - case 247: + case 241: { context->incrSwitchNestingLevel(); } break; - case 248: + case 242: { (yyval.interm.intermSwitch) = context->addSwitch((yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermAggregate), (yylsp[-5])); @@ -4573,7 +4438,7 @@ yyreduce: break; - case 249: + case 243: { (yyval.interm.intermCase) = context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2])); @@ -4581,7 +4446,7 @@ yyreduce: break; - case 250: + case 244: { (yyval.interm.intermCase) = context->addDefault((yylsp[-1])); @@ -4589,40 +4454,37 @@ yyreduce: break; - case 251: + case 245: { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); - if (context->boolErrorCheck((yyvsp[0].interm.intermTypedNode)->getLine(), (yyvsp[0].interm.intermTypedNode))) - context->recover(); + context->checkIsScalarBool((yyvsp[0].interm.intermTypedNode)->getLine(), (yyvsp[0].interm.intermTypedNode)); } break; - case 252: + case 246: { TIntermNode *intermNode; - if (context->boolErrorCheck((yylsp[-2]), (yyvsp[-3].interm.type))) - context->recover(); + context->checkIsScalarBool((yylsp[-2]), (yyvsp[-3].interm.type)); if (!context->executeInitializer((yylsp[-2]), *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), (yyvsp[0].interm.intermTypedNode), &intermNode)) (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); else { - context->recover(); (yyval.interm.intermTypedNode) = 0; } } break; - case 253: + case 247: { context->symbolTable.push(); context->incrLoopNestingLevel(); } break; - case 254: + case 248: { context->symbolTable.pop(); @@ -4632,17 +4494,16 @@ yyreduce: break; - case 255: + case 249: { context->incrLoopNestingLevel(); } break; - case 256: + case 250: { - if (context->boolErrorCheck((yylsp[0]), (yyvsp[-2].interm.intermTypedNode))) - context->recover(); + context->checkIsScalarBool((yylsp[0]), (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0, (yyvsp[-5].interm.intermNode), (yylsp[-4])); context->decrLoopNestingLevel(); @@ -4650,13 +4511,13 @@ yyreduce: break; - case 257: + case 251: { context->symbolTable.push(); context->incrLoopNestingLevel(); } break; - case 258: + case 252: { context->symbolTable.pop(); @@ -4666,7 +4527,7 @@ yyreduce: break; - case 259: + case 253: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4674,7 +4535,7 @@ yyreduce: break; - case 260: + case 254: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4682,7 +4543,7 @@ yyreduce: break; - case 261: + case 255: { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); @@ -4690,7 +4551,7 @@ yyreduce: break; - case 262: + case 256: { (yyval.interm.intermTypedNode) = 0; @@ -4698,7 +4559,7 @@ yyreduce: break; - case 263: + case 257: { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); @@ -4707,7 +4568,7 @@ yyreduce: break; - case 264: + case 258: { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); @@ -4716,7 +4577,7 @@ yyreduce: break; - case 265: + case 259: { (yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1])); @@ -4724,7 +4585,7 @@ yyreduce: break; - case 266: + case 260: { (yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1])); @@ -4732,7 +4593,7 @@ yyreduce: break; - case 267: + case 261: { (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1])); @@ -4740,7 +4601,7 @@ yyreduce: break; - case 268: + case 262: { (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2])); @@ -4748,7 +4609,7 @@ yyreduce: break; - case 269: + case 263: { FRAG_ONLY("discard", (yylsp[-1])); @@ -4757,7 +4618,7 @@ yyreduce: break; - case 270: + case 264: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4766,7 +4627,7 @@ yyreduce: break; - case 271: + case 265: { (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode), (yyloc)); @@ -4775,7 +4636,7 @@ yyreduce: break; - case 272: + case 266: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4783,7 +4644,7 @@ yyreduce: break; - case 273: + case 267: { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); @@ -4791,7 +4652,7 @@ yyreduce: break; - case 274: + case 268: { context->parseFunctionPrototype((yylsp[0]), (yyvsp[0].interm).function, &(yyvsp[0].interm).intermAggregate); @@ -4799,7 +4660,7 @@ yyreduce: break; - case 275: + case 269: { (yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermAggregate), (yylsp[-2])); diff --git a/chromium/third_party/angle/src/compiler/translator/glslang_tab.h b/chromium/third_party/angle/src/compiler/translator/glslang_tab.h index 7331594a448..d0e691d844f 100644 --- a/chromium/third_party/angle/src/compiler/translator/glslang_tab.h +++ b/chromium/third_party/angle/src/compiler/translator/glslang_tab.h @@ -208,6 +208,7 @@ union YYSTYPE TIntermCase* intermCase; }; union { + TTypeSpecifierNonArray typeSpecifierNonArray; TPublicType type; TPrecision precision; TLayoutQualifier layoutQualifier; @@ -216,6 +217,8 @@ union YYSTYPE TParameter param; TField* field; TFieldList* fieldList; + TQualifierWrapperBase *qualifierWrapper; + TTypeQualifierBuilder *typeQualifierBuilder; }; } interm; diff --git a/chromium/third_party/angle/src/compiler/translator/intermOut.cpp b/chromium/third_party/angle/src/compiler/translator/intermOut.cpp index 6dca547f086..aed53d4ec4d 100644 --- a/chromium/third_party/angle/src/compiler/translator/intermOut.cpp +++ b/chromium/third_party/angle/src/compiler/translator/intermOut.cpp @@ -42,12 +42,15 @@ class TOutputTraverser : public TIntermTraverser protected: void visitSymbol(TIntermSymbol *) override; void visitConstantUnion(TIntermConstantUnion *) override; + bool visitSwizzle(Visit visit, TIntermSwizzle *node) override; bool visitBinary(Visit visit, TIntermBinary *) override; bool visitUnary(Visit visit, TIntermUnary *) override; - bool visitSelection(Visit visit, TIntermSelection *) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + bool visitIfElse(Visit visit, TIntermIfElse *node) override; bool visitAggregate(Visit visit, TIntermAggregate *) override; bool visitLoop(Visit visit, TIntermLoop *) override; bool visitBranch(Visit visit, TIntermBranch *) override; + // TODO: Add missing visit functions }; // @@ -82,6 +85,14 @@ void TOutputTraverser::visitSymbol(TIntermSymbol *node) sink << "(" << node->getCompleteString() << ")\n"; } +bool TOutputTraverser::visitSwizzle(Visit visit, TIntermSwizzle *node) +{ + TInfoSinkBase &out = sink; + OutputTreeText(out, node, mDepth); + out << "vector swizzle"; + return true; +} + bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node) { TInfoSinkBase& out = sink; @@ -151,9 +162,6 @@ bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node) case EOpIndexDirectInterfaceBlock: out << "direct index for interface block"; break; - case EOpVectorSwizzle: - out << "vector swizzle"; - break; case EOpAdd: out << "add"; @@ -457,13 +465,13 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node) return true; } -bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection *node) +bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node) { TInfoSinkBase &out = sink; OutputTreeText(out, node, mDepth); - out << "Test condition and select"; + out << "Ternary selection"; out << " (" << node->getCompleteString() << ")\n"; ++mDepth; @@ -473,6 +481,38 @@ bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection *node) node->getCondition()->traverse(this); OutputTreeText(sink, node, mDepth); + if (node->getTrueExpression()) + { + out << "true case\n"; + node->getTrueExpression()->traverse(this); + } + if (node->getFalseExpression()) + { + OutputTreeText(sink, node, mDepth); + out << "false case\n"; + node->getFalseExpression()->traverse(this); + } + + --mDepth; + + return false; +} + +bool TOutputTraverser::visitIfElse(Visit visit, TIntermIfElse *node) +{ + TInfoSinkBase &out = sink; + + OutputTreeText(out, node, mDepth); + + out << "If test\n"; + + ++mDepth; + + OutputTreeText(sink, node, mDepth); + out << "Condition\n"; + node->getCondition()->traverse(this); + + OutputTreeText(sink, node, mDepth); if (node->getTrueBlock()) { out << "true case\n"; diff --git a/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp b/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp deleted file mode 100644 index 790974a2bf5..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/InfoSink.h" -#include "compiler/translator/ParseContext.h" -#include "compiler/translator/depgraph/DependencyGraphOutput.h" -#include "compiler/translator/timing/RestrictFragmentShaderTiming.h" - -RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase& sink) - : mSink(sink) - , mNumErrors(0) -{ - // Sampling ops found only in fragment shaders. - mSamplingOps.insert("texture2D(s21;vf2;f1;"); - mSamplingOps.insert("texture2DProj(s21;vf3;f1;"); - mSamplingOps.insert("texture2DProj(s21;vf4;f1;"); - mSamplingOps.insert("textureCube(sC1;vf3;f1;"); - // Sampling ops found in both vertex and fragment shaders. - mSamplingOps.insert("texture2D(s21;vf2;"); - mSamplingOps.insert("texture2DProj(s21;vf3;"); - mSamplingOps.insert("texture2DProj(s21;vf4;"); - mSamplingOps.insert("textureCube(sC1;vf3;"); - // Sampling ops provided by OES_EGL_image_external. - mSamplingOps.insert("texture2D(1;vf2;"); - mSamplingOps.insert("texture2DProj(1;vf3;"); - mSamplingOps.insert("texture2DProj(1;vf4;"); - // Sampling ops provided by ARB_texture_rectangle. - mSamplingOps.insert("texture2DRect(1;vf2;"); - mSamplingOps.insert("texture2DRectProj(1;vf3;"); - mSamplingOps.insert("texture2DRectProj(1;vf4;"); - // Sampling ops provided by EXT_shader_texture_lod. - mSamplingOps.insert("texture2DLodEXT(1;vf2;f1;"); - mSamplingOps.insert("texture2DProjLodEXT(1;vf3;f1;"); - mSamplingOps.insert("texture2DProjLodEXT(1;vf4;f1;"); - mSamplingOps.insert("textureCubeLodEXT(1;vf4;f1;"); - mSamplingOps.insert("texture2DGradEXT(1;vf2;vf2;vf2;"); - mSamplingOps.insert("texture2DProjGradEXT(1;vf3;vf2;vf2;"); - mSamplingOps.insert("texture2DProjGradEXT(1;vf4;vf2;vf2;"); - mSamplingOps.insert("textureCubeGradEXT(1;vf3;vf3;vf3;"); -} - -// FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc. -// can vary based on the value of the input arguments. If so, we should restrict those as well. -void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& graph) -{ - mNumErrors = 0; - - // FIXME(mvujovic): The dependency graph does not support user defined function calls right now, - // so we generate errors for them. - validateUserDefinedFunctionCallUsage(graph); - - // Starting from each sampler, traverse the dependency graph and generate an error each time we - // hit a node where sampler dependent values are not allowed. - for (auto samplerSymbol : graph.samplerSymbols()) - { - clearVisited(); - samplerSymbol->traverse(this); - } -} - -void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph) -{ - for (const auto* functionCall : graph.userDefinedFunctionCalls()) - { - beginError(functionCall->getIntermFunctionCall()); - mSink << "A call to a user defined function is not permitted.\n"; - } -} - -void RestrictFragmentShaderTiming::beginError(const TIntermNode* node) -{ - ++mNumErrors; - mSink.prefix(EPrefixError); - mSink.location(node->getLine()); -} - -bool RestrictFragmentShaderTiming::isSamplingOp(const TIntermAggregate* intermFunctionCall) const -{ - return !intermFunctionCall->isUserDefined() && - mSamplingOps.find(intermFunctionCall->getName()) != mSamplingOps.end(); -} - -void RestrictFragmentShaderTiming::visitArgument(TGraphArgument* parameter) -{ - // Texture cache access time might leak sensitive information. - // Thus, we restrict sampler dependent values from affecting the coordinate or LOD bias of a - // sampling operation. - if (isSamplingOp(parameter->getIntermFunctionCall())) { - switch (parameter->getArgumentNumber()) { - case 1: - // Second argument (coord) - beginError(parameter->getIntermFunctionCall()); - mSink << "An expression dependent on a sampler is not permitted to be the" - << " coordinate argument of a sampling operation.\n"; - break; - case 2: - // Third argument (bias) - beginError(parameter->getIntermFunctionCall()); - mSink << "An expression dependent on a sampler is not permitted to be the" - << " bias argument of a sampling operation.\n"; - break; - default: - // First argument (sampler) - break; - } - } -} - -void RestrictFragmentShaderTiming::visitSelection(TGraphSelection* selection) -{ - beginError(selection->getIntermSelection()); - mSink << "An expression dependent on a sampler is not permitted in a conditional statement.\n"; -} - -void RestrictFragmentShaderTiming::visitLoop(TGraphLoop* loop) -{ - beginError(loop->getIntermLoop()); - mSink << "An expression dependent on a sampler is not permitted in a loop condition.\n"; -} - -void RestrictFragmentShaderTiming::visitLogicalOp(TGraphLogicalOp* logicalOp) -{ - beginError(logicalOp->getIntermLogicalOp()); - mSink << "An expression dependent on a sampler is not permitted on the left hand side of a logical " - << logicalOp->getOpString() - << " operator.\n"; -} diff --git a/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h b/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h deleted file mode 100644 index b8c7e829564..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_ -#define COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_ - -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/depgraph/DependencyGraph.h" - -class TInfoSinkBase; - -class RestrictFragmentShaderTiming : TDependencyGraphTraverser -{ - public: - RestrictFragmentShaderTiming(TInfoSinkBase &sink); - void enforceRestrictions(const TDependencyGraph &graph); - int numErrors() const { return mNumErrors; } - - void visitArgument(TGraphArgument *parameter) override; - void visitSelection(TGraphSelection *selection) override; - void visitLoop(TGraphLoop *loop) override; - void visitLogicalOp(TGraphLogicalOp *logicalOp) override; - - private: - void beginError(const TIntermNode *node); - void validateUserDefinedFunctionCallUsage(const TDependencyGraph &graph); - bool isSamplingOp(const TIntermAggregate *intermFunctionCall) const; - - TInfoSinkBase &mSink; - int mNumErrors; - - typedef std::set<TString> StringSet; - StringSet mSamplingOps; -}; - -#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp b/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp deleted file mode 100644 index 7c1208a2986..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/timing/RestrictVertexShaderTiming.h" - -void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node) -{ - if (IsSampler(node->getBasicType())) { - ++mNumErrors; - mSink.message(EPrefixError, - node->getLine(), - "Samplers are not permitted in vertex shaders.\n"); - } -} diff --git a/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h b/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h deleted file mode 100644 index 23a8217722e..00000000000 --- a/chromium/third_party/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_ -#define COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_ - -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/InfoSink.h" - -class TInfoSinkBase; - -class RestrictVertexShaderTiming : public TIntermTraverser { -public: - RestrictVertexShaderTiming(TInfoSinkBase& sink) - : TIntermTraverser(true, false, false) - , mSink(sink) - , mNumErrors(0) {} - - void enforceRestrictions(TIntermNode* root) { root->traverse(this); } - int numErrors() { return mNumErrors; } - - void visitSymbol(TIntermSymbol *) override; - -private: - TInfoSinkBase& mSink; - int mNumErrors; -}; - -#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_ diff --git a/chromium/third_party/angle/src/compiler/translator/util.cpp b/chromium/third_party/angle/src/compiler/translator/util.cpp index 01311372066..d6339a87345 100644 --- a/chromium/third_party/angle/src/compiler/translator/util.cpp +++ b/chromium/third_party/angle/src/compiler/translator/util.cpp @@ -278,6 +278,215 @@ InterpolationType GetInterpolationType(TQualifier qualifier) } } +TType GetShaderVariableBasicType(const sh::ShaderVariable &var) +{ + switch (var.type) + { + case GL_FLOAT: + return TType(EbtFloat); + case GL_FLOAT_VEC2: + return TType(EbtFloat, 2); + case GL_FLOAT_VEC3: + return TType(EbtFloat, 3); + case GL_FLOAT_VEC4: + return TType(EbtFloat, 4); + case GL_FLOAT_MAT2: + return TType(EbtFloat, 2, 2); + case GL_FLOAT_MAT3: + return TType(EbtFloat, 3, 3); + case GL_FLOAT_MAT4: + return TType(EbtFloat, 4, 4); + case GL_FLOAT_MAT2x3: + return TType(EbtFloat, 2, 3); + case GL_FLOAT_MAT2x4: + return TType(EbtFloat, 2, 4); + case GL_FLOAT_MAT3x2: + return TType(EbtFloat, 3, 2); + case GL_FLOAT_MAT3x4: + return TType(EbtFloat, 3, 4); + case GL_FLOAT_MAT4x2: + return TType(EbtFloat, 4, 2); + case GL_FLOAT_MAT4x3: + return TType(EbtFloat, 4, 3); + case GL_INT: + return TType(EbtInt); + case GL_INT_VEC2: + return TType(EbtInt, 2); + case GL_INT_VEC3: + return TType(EbtInt, 3); + case GL_INT_VEC4: + return TType(EbtInt, 4); + case GL_UNSIGNED_INT: + return TType(EbtUInt); + case GL_UNSIGNED_INT_VEC2: + return TType(EbtUInt, 2); + case GL_UNSIGNED_INT_VEC3: + return TType(EbtUInt, 3); + case GL_UNSIGNED_INT_VEC4: + return TType(EbtUInt, 4); + default: + UNREACHABLE(); + return TType(); + } +} + +TType GetShaderVariableType(const sh::ShaderVariable &var) +{ + TType type; + if (var.isStruct()) + { + TFieldList *fields = new TFieldList; + TSourceLoc loc; + for (const auto &field : var.fields) + { + TType *fieldType = new TType(GetShaderVariableType(field)); + fields->push_back(new TField(fieldType, new TString(field.name.c_str()), loc)); + } + TStructure *structure = new TStructure(new TString(var.structName.c_str()), fields); + + type.setBasicType(EbtStruct); + type.setStruct(structure); + } + else + { + type = GetShaderVariableBasicType(var); + } + + if (var.isArray()) + { + type.setArraySize(var.elementCount()); + } + return type; +} + +TOperator TypeToConstructorOperator(const TType &type) +{ + switch (type.getBasicType()) + { + case EbtFloat: + if (type.isMatrix()) + { + switch (type.getCols()) + { + case 2: + switch (type.getRows()) + { + case 2: + return EOpConstructMat2; + case 3: + return EOpConstructMat2x3; + case 4: + return EOpConstructMat2x4; + default: + break; + } + break; + + case 3: + switch (type.getRows()) + { + case 2: + return EOpConstructMat3x2; + case 3: + return EOpConstructMat3; + case 4: + return EOpConstructMat3x4; + default: + break; + } + break; + + case 4: + switch (type.getRows()) + { + case 2: + return EOpConstructMat4x2; + case 3: + return EOpConstructMat4x3; + case 4: + return EOpConstructMat4; + default: + break; + } + break; + } + } + else + { + switch (type.getNominalSize()) + { + case 1: + return EOpConstructFloat; + case 2: + return EOpConstructVec2; + case 3: + return EOpConstructVec3; + case 4: + return EOpConstructVec4; + default: + break; + } + } + break; + + case EbtInt: + switch (type.getNominalSize()) + { + case 1: + return EOpConstructInt; + case 2: + return EOpConstructIVec2; + case 3: + return EOpConstructIVec3; + case 4: + return EOpConstructIVec4; + default: + break; + } + break; + + case EbtUInt: + switch (type.getNominalSize()) + { + case 1: + return EOpConstructUInt; + case 2: + return EOpConstructUVec2; + case 3: + return EOpConstructUVec3; + case 4: + return EOpConstructUVec4; + default: + break; + } + break; + + case EbtBool: + switch (type.getNominalSize()) + { + case 1: + return EOpConstructBool; + case 2: + return EOpConstructBVec2; + case 3: + return EOpConstructBVec3; + case 4: + return EOpConstructBVec4; + default: + break; + } + break; + + case EbtStruct: + return EOpConstructStruct; + + default: + break; + } + + return EOpNull; +} + GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable) : mSymbolTable(symbolTable) { @@ -324,7 +533,7 @@ void GetVariableTraverser::traverse(const TType &type, VarT variable; variable.name = name.c_str(); - variable.arraySize = static_cast<unsigned int>(type.getArraySize()); + variable.arraySize = type.getArraySize(); if (!structure) { @@ -357,4 +566,52 @@ template void GetVariableTraverser::traverse(const TType &, const TString &, std template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *); template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *); +// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier +bool CanBeInvariantESSL1(TQualifier qualifier) +{ + return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) || + IsBuiltinOutputVariable(qualifier) || + (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing); +} + +// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier +// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier +bool CanBeInvariantESSL3OrGreater(TQualifier qualifier) +{ + return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut || + IsBuiltinOutputVariable(qualifier); +} + +bool IsBuiltinOutputVariable(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqPosition: + case EvqPointSize: + case EvqFragDepth: + case EvqFragDepthEXT: + case EvqFragColor: + case EvqSecondaryFragColorEXT: + case EvqFragData: + case EvqSecondaryFragDataEXT: + return true; + default: + break; + } + return false; +} + +bool IsBuiltinFragmentInputVariable(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqFragCoord: + case EvqPointCoord: + case EvqFrontFacing: + return true; + default: + break; + } + return false; } +} // namespace sh diff --git a/chromium/third_party/angle/src/compiler/translator/util.h b/chromium/third_party/angle/src/compiler/translator/util.h index ea7a35a352a..4c1713a8a85 100644 --- a/chromium/third_party/angle/src/compiler/translator/util.h +++ b/chromium/third_party/angle/src/compiler/translator/util.h @@ -12,6 +12,7 @@ #include "angle_gl.h" #include <GLSLANG/ShaderLang.h> +#include "compiler/translator/Operator.h" #include "compiler/translator/Types.h" // strtof_clamp is like strtof but @@ -37,6 +38,11 @@ bool IsVarying(TQualifier qualifier); InterpolationType GetInterpolationType(TQualifier qualifier); TString ArrayString(const TType &type); +TType GetShaderVariableBasicType(const sh::ShaderVariable &var); +TType GetShaderVariableType(const sh::ShaderVariable &var); + +TOperator TypeToConstructorOperator(const TType &type); + class GetVariableTraverser : angle::NonCopyable { public: @@ -60,6 +66,10 @@ class GetVariableTraverser : angle::NonCopyable const TSymbolTable &mSymbolTable; }; +bool IsBuiltinOutputVariable(TQualifier qualifier); +bool IsBuiltinFragmentInputVariable(TQualifier qualifier); +bool CanBeInvariantESSL1(TQualifier qualifier); +bool CanBeInvariantESSL3OrGreater(TQualifier qualifier); } #endif // COMPILER_TRANSLATOR_UTIL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/copyimage.cpp b/chromium/third_party/angle/src/image_util/copyimage.cpp index 3291ea8b93f..cc079081584 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/copyimage.cpp +++ b/chromium/third_party/angle/src/image_util/copyimage.cpp @@ -6,17 +6,17 @@ // copyimage.cpp: Defines image copying functions -#include "libANGLE/renderer/copyimage.h" +#include "image_util/copyimage.h" -namespace rx +namespace angle { void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest) { - uint32_t argb = *reinterpret_cast<const uint32_t *>(source); + uint32_t argb = *reinterpret_cast<const uint32_t *>(source); *reinterpret_cast<uint32_t *>(dest) = (argb & 0xFF00FF00) | // Keep alpha and green (argb & 0x00FF0000) >> 16 | // Move red to blue (argb & 0x000000FF) << 16; // Move blue to red } -} // namespace rx +} // namespace angle diff --git a/chromium/third_party/angle/src/libANGLE/renderer/copyimage.h b/chromium/third_party/angle/src/image_util/copyimage.h index efd5b17c0b1..bc8c1390eb4 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/copyimage.h +++ b/chromium/third_party/angle/src/image_util/copyimage.h @@ -6,15 +6,16 @@ // copyimage.h: Defines image copying functions -#ifndef LIBANGLE_RENDERER_D3D_COPYIMAGE_H_ -#define LIBANGLE_RENDERER_D3D_COPYIMAGE_H_ +#ifndef IMAGEUTIL_COPYIMAGE_H_ +#define IMAGEUTIL_COPYIMAGE_H_ -#include "common/mathutil.h" -#include "libANGLE/angletypes.h" +#include "common/Color.h" + +#include "image_util/imageformats.h" #include <stdint.h> -namespace rx +namespace angle { template <typename sourceType, typename colorDataType> @@ -28,8 +29,8 @@ void CopyPixel(const uint8_t *source, uint8_t *dest); void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest); -} // namespace rx +} // namespace angle #include "copyimage.inl" -#endif // LIBANGLE_RENDERER_D3D_COPYIMAGE_H_ +#endif // IMAGEUTIL_COPYIMAGE_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/copyimage.inl b/chromium/third_party/angle/src/image_util/copyimage.inl index 0498cf7750a..dbada812918 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/copyimage.inl +++ b/chromium/third_party/angle/src/image_util/copyimage.inl @@ -6,19 +6,21 @@ // copyimage.inl: Defines image copying functions -namespace rx +namespace angle { template <typename sourceType, typename colorDataType> inline void ReadColor(const uint8_t *source, uint8_t *dest) { - sourceType::readColor(reinterpret_cast<gl::Color<colorDataType>*>(dest), reinterpret_cast<const sourceType*>(source)); + sourceType::readColor(reinterpret_cast<Color<colorDataType>*>(dest), + reinterpret_cast<const sourceType*>(source)); } template <typename destType, typename colorDataType> inline void WriteColor(const uint8_t *source, uint8_t *dest) { - destType::writeColor(reinterpret_cast<destType*>(dest), reinterpret_cast<const gl::Color<colorDataType>*>(source)); + destType::writeColor(reinterpret_cast<destType*>(dest), + reinterpret_cast<const Color<colorDataType>*>(source)); } template <typename sourceType, typename destType, typename colorDataType> @@ -29,4 +31,4 @@ inline void CopyPixel(const uint8_t *source, uint8_t *dest) WriteColor<destType, colorDataType>(&temp, dest); } -} +} // namespace angle diff --git a/chromium/third_party/angle/src/image_util/generatemip.h b/chromium/third_party/angle/src/image_util/generatemip.h new file mode 100644 index 00000000000..a89db823b07 --- /dev/null +++ b/chromium/third_party/angle/src/image_util/generatemip.h @@ -0,0 +1,34 @@ +// +// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// generatemip.h: Defines the GenerateMip function, templated on the format +// type of the image for which mip levels are being generated. + +#ifndef IMAGEUTIL_GENERATEMIP_H_ +#define IMAGEUTIL_GENERATEMIP_H_ + +#include <stddef.h> +#include <stdint.h> + +namespace angle +{ + +template <typename T> +inline void GenerateMip(size_t sourceWidth, + size_t sourceHeight, + size_t sourceDepth, + const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourceDepthPitch, + uint8_t *destData, + size_t destRowPitch, + size_t destDepthPitch); + +} // namespace angle + +#include "generatemip.inl" + +#endif // IMAGEUTIL_GENERATEMIP_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/generatemip.inl b/chromium/third_party/angle/src/image_util/generatemip.inl index 265783641e5..e737daf7561 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/generatemip.inl +++ b/chromium/third_party/angle/src/image_util/generatemip.inl @@ -9,7 +9,9 @@ #include "common/mathutil.h" -namespace rx +#include "image_util/imageformats.h" + +namespace angle { namespace priv @@ -245,7 +247,7 @@ static MipGenerationFunction GetMipGenerationFunction(size_t sourceWidth, size_t return NULL; } -} +} // namespace priv template <typename T> inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth, @@ -263,4 +265,4 @@ inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDe mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch); } -} +} // namespace angle diff --git a/chromium/third_party/angle/src/image_util/imageformats.cpp b/chromium/third_party/angle/src/image_util/imageformats.cpp new file mode 100644 index 00000000000..f5e51f054c7 --- /dev/null +++ b/chromium/third_party/angle/src/image_util/imageformats.cpp @@ -0,0 +1,1688 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// imageformats.cpp: Defines image format types with functions for mip generation +// and copying. + +#include "image_util/imageformats.h" + +#include "common/mathutil.h" + +namespace angle +{ + +void L8::readColor(gl::ColorF *dst, const L8 *src) +{ + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = 1.0f; +} + +void L8::writeColor(L8 *dst, const gl::ColorF *src) +{ + dst->L = gl::floatToNormalized<uint8_t>(src->red); +} + +void L8::average(L8 *dst, const L8 *src1, const L8 *src2) +{ + dst->L = gl::average(src1->L, src2->L); +} + +void R8::readColor(gl::ColorUI *dst, const R8 *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R8::readColor(gl::ColorF *dst, const R8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8::writeColor(R8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); +} + +void R8::writeColor(R8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); +} + +void R8::average(R8 *dst, const R8 *src1, const R8 *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void A8::readColor(gl::ColorF *dst, const A8 *src) +{ + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = gl::normalizedToFloat(src->A); +} + +void A8::writeColor(A8 *dst, const gl::ColorF *src) +{ + dst->A = gl::floatToNormalized<uint8_t>(src->alpha); +} + +void A8::average(A8 *dst, const A8 *src1, const A8 *src2) +{ + dst->A = gl::average(src1->A, src2->A); +} + +void L8A8::readColor(gl::ColorF *dst, const L8A8 *src) +{ + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::normalizedToFloat(src->A); +} + +void L8A8::writeColor(L8A8 *dst, const gl::ColorF *src) +{ + dst->L = gl::floatToNormalized<uint8_t>(src->red); + dst->A = gl::floatToNormalized<uint8_t>(src->alpha); +} + +void L8A8::average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2) +{ + *(uint16_t *)dst = (((*(uint16_t *)src1 ^ *(uint16_t *)src2) & 0xFEFE) >> 1) + + (*(uint16_t *)src1 & *(uint16_t *)src2); +} + +void A8L8::readColor(gl::ColorF *dst, const A8L8 *src) +{ + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::normalizedToFloat(src->A); +} + +void A8L8::writeColor(A8L8 *dst, const gl::ColorF *src) +{ + dst->L = gl::floatToNormalized<uint8_t>(src->red); + dst->A = gl::floatToNormalized<uint8_t>(src->alpha); +} + +void A8L8::average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) +{ + *(uint16_t *)dst = (((*(uint16_t *)src1 ^ *(uint16_t *)src2) & 0xFEFE) >> 1) + + (*(uint16_t *)src1 & *(uint16_t *)src2); +} + +void R8G8::readColor(gl::ColorUI *dst, const R8G8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R8G8::readColor(gl::ColorF *dst, const R8G8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8G8::writeColor(R8G8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); + dst->G = static_cast<uint8_t>(src->green); +} + +void R8G8::writeColor(R8G8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); + dst->G = gl::floatToNormalized<uint8_t>(src->green); +} + +void R8G8::average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2) +{ + *(uint16_t *)dst = (((*(uint16_t *)src1 ^ *(uint16_t *)src2) & 0xFEFE) >> 1) + + (*(uint16_t *)src1 & *(uint16_t *)src2); +} + +void R8G8B8::readColor(gl::ColorUI *dst, const R8G8B8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->G; + dst->alpha = 1; +} + +void R8G8B8::readColor(gl::ColorF *dst, const R8G8B8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R8G8B8::writeColor(R8G8B8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); + dst->G = static_cast<uint8_t>(src->green); + dst->B = static_cast<uint8_t>(src->blue); +} + +void R8G8B8::writeColor(R8G8B8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); + dst->G = gl::floatToNormalized<uint8_t>(src->green); + dst->B = gl::floatToNormalized<uint8_t>(src->blue); +} + +void R8G8B8::average(R8G8B8 *dst, const R8G8B8 *src1, const R8G8B8 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void B8G8R8::readColor(gl::ColorUI *dst, const B8G8R8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->G; + dst->alpha = 1; +} + +void B8G8R8::readColor(gl::ColorF *dst, const B8G8R8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void B8G8R8::writeColor(B8G8R8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); + dst->G = static_cast<uint8_t>(src->green); + dst->B = static_cast<uint8_t>(src->blue); +} + +void B8G8R8::writeColor(B8G8R8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); + dst->G = gl::floatToNormalized<uint8_t>(src->green); + dst->B = gl::floatToNormalized<uint8_t>(src->blue); +} + +void B8G8R8::average(B8G8R8 *dst, const B8G8R8 *src1, const B8G8R8 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R5G6B5::readColor(gl::ColorF *dst, const R5G6B5 *src) +{ + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGB)); + dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->RGB)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGB)); + dst->alpha = 1.0f; +} + +void R5G6B5::writeColor(R5G6B5 *dst, const gl::ColorF *src) +{ + dst->RGB = gl::shiftData<5, 11>(gl::floatToNormalized<5, uint16_t>(src->red)) | + gl::shiftData<6, 5>(gl::floatToNormalized<6, uint16_t>(src->green)) | + gl::shiftData<5, 0>(gl::floatToNormalized<5, uint16_t>(src->blue)); +} + +void R5G6B5::average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2) +{ + dst->RGB = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGB), + gl::getShiftedData<5, 11>(src2->RGB))) | + gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->RGB), + gl::getShiftedData<6, 5>(src2->RGB))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGB), + gl::getShiftedData<5, 0>(src2->RGB))); +} + +void B5G6R5::readColor(gl::ColorF *dst, const B5G6R5 *src) +{ + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->BGR)); + dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->BGR)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->BGR)); + dst->alpha = 1.0f; +} + +void B5G6R5::writeColor(B5G6R5 *dst, const gl::ColorF *src) +{ + dst->BGR = gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)) | + gl::shiftData<6, 5>(gl::floatToNormalized<6, unsigned short>(src->green)) | + gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)); +} + +void B5G6R5::average(B5G6R5 *dst, const B5G6R5 *src1, const B5G6R5 *src2) +{ + dst->BGR = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->BGR), + gl::getShiftedData<5, 11>(src2->BGR))) | + gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->BGR), + gl::getShiftedData<6, 5>(src2->BGR))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->BGR), + gl::getShiftedData<5, 0>(src2->BGR))); +} + +void A8R8G8B8::readColor(gl::ColorUI *dst, const A8R8G8B8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void A8R8G8B8::readColor(gl::ColorF *dst, const A8R8G8B8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void A8R8G8B8::writeColor(A8R8G8B8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); + dst->G = static_cast<uint8_t>(src->green); + dst->B = static_cast<uint8_t>(src->blue); + dst->A = static_cast<uint8_t>(src->alpha); +} + +void A8R8G8B8::writeColor(A8R8G8B8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); + dst->G = gl::floatToNormalized<uint8_t>(src->green); + dst->B = gl::floatToNormalized<uint8_t>(src->blue); + dst->A = gl::floatToNormalized<uint8_t>(src->alpha); +} + +void A8R8G8B8::average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); +} + +void R8G8B8A8::readColor(gl::ColorUI *dst, const R8G8B8A8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R8G8B8A8::readColor(gl::ColorF *dst, const R8G8B8A8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R8G8B8A8::writeColor(R8G8B8A8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); + dst->G = static_cast<uint8_t>(src->green); + dst->B = static_cast<uint8_t>(src->blue); + dst->A = static_cast<uint8_t>(src->alpha); +} + +void R8G8B8A8::writeColor(R8G8B8A8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); + dst->G = gl::floatToNormalized<uint8_t>(src->green); + dst->B = gl::floatToNormalized<uint8_t>(src->blue); + dst->A = gl::floatToNormalized<uint8_t>(src->alpha); +} + +void R8G8B8A8::average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); +} + +void B8G8R8A8::readColor(gl::ColorUI *dst, const B8G8R8A8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void B8G8R8A8::readColor(gl::ColorF *dst, const B8G8R8A8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void B8G8R8A8::writeColor(B8G8R8A8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); + dst->G = static_cast<uint8_t>(src->green); + dst->B = static_cast<uint8_t>(src->blue); + dst->A = static_cast<uint8_t>(src->alpha); +} + +void B8G8R8A8::writeColor(B8G8R8A8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); + dst->G = gl::floatToNormalized<uint8_t>(src->green); + dst->B = gl::floatToNormalized<uint8_t>(src->blue); + dst->A = gl::floatToNormalized<uint8_t>(src->alpha); +} + +void B8G8R8A8::average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); +} + +void B8G8R8X8::readColor(gl::ColorUI *dst, const B8G8R8X8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void B8G8R8X8::readColor(gl::ColorF *dst, const B8G8R8X8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void B8G8R8X8::writeColor(B8G8R8X8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint8_t>(src->red); + dst->G = static_cast<uint8_t>(src->green); + dst->B = static_cast<uint8_t>(src->blue); + dst->X = 255; +} + +void B8G8R8X8::writeColor(B8G8R8X8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint8_t>(src->red); + dst->G = gl::floatToNormalized<uint8_t>(src->green); + dst->B = gl::floatToNormalized<uint8_t>(src->blue); + dst->X = 255; +} + +void B8G8R8X8::average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); + dst->X = 255; +} + +void A1R5G5B5::readColor(gl::ColorF *dst, const A1R5G5B5 *src) +{ + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->ARGB)); + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->ARGB)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->ARGB)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->ARGB)); +} + +void A1R5G5B5::writeColor(A1R5G5B5 *dst, const gl::ColorF *src) +{ + dst->ARGB = gl::shiftData<1, 15>(gl::floatToNormalized<1, uint16_t>(src->alpha)) | + gl::shiftData<5, 10>(gl::floatToNormalized<5, uint16_t>(src->red)) | + gl::shiftData<5, 5>(gl::floatToNormalized<5, uint16_t>(src->green)) | + gl::shiftData<5, 0>(gl::floatToNormalized<5, uint16_t>(src->blue)); +} + +void A1R5G5B5::average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2) +{ + dst->ARGB = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->ARGB), + gl::getShiftedData<1, 15>(src2->ARGB))) | + gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->ARGB), + gl::getShiftedData<5, 10>(src2->ARGB))) | + gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->ARGB), + gl::getShiftedData<5, 5>(src2->ARGB))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->ARGB), + gl::getShiftedData<5, 0>(src2->ARGB))); +} + +void R5G5B5A1::readColor(gl::ColorF *dst, const R5G5B5A1 *src) +{ + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGBA)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 6>(src->RGBA)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 1>(src->RGBA)); + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 0>(src->RGBA)); +} + +void R5G5B5A1::writeColor(R5G5B5A1 *dst, const gl::ColorF *src) +{ + dst->RGBA = gl::shiftData<5, 11>(gl::floatToNormalized<5, uint16_t>(src->red)) | + gl::shiftData<5, 6>(gl::floatToNormalized<5, uint16_t>(src->green)) | + gl::shiftData<5, 1>(gl::floatToNormalized<5, uint16_t>(src->blue)) | + gl::shiftData<1, 0>(gl::floatToNormalized<1, uint16_t>(src->alpha)); +} + +void R5G5B5A1::average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2) +{ + dst->RGBA = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGBA), + gl::getShiftedData<5, 11>(src2->RGBA))) | + gl::shiftData<5, 6>(gl::average(gl::getShiftedData<5, 6>(src1->RGBA), + gl::getShiftedData<5, 6>(src2->RGBA))) | + gl::shiftData<5, 1>(gl::average(gl::getShiftedData<5, 1>(src1->RGBA), + gl::getShiftedData<5, 1>(src2->RGBA))) | + gl::shiftData<1, 0>(gl::average(gl::getShiftedData<1, 0>(src1->RGBA), + gl::getShiftedData<1, 0>(src2->RGBA))); +} + +void R4G4B4A4::readColor(gl::ColorF *dst, const R4G4B4A4 *src) +{ + dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->RGBA)); + dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->RGBA)); + dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->RGBA)); + dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->RGBA)); +} + +void R4G4B4A4::writeColor(R4G4B4A4 *dst, const gl::ColorF *src) +{ + dst->RGBA = gl::shiftData<4, 12>(gl::floatToNormalized<4, uint16_t>(src->red)) | + gl::shiftData<4, 8>(gl::floatToNormalized<4, uint16_t>(src->green)) | + gl::shiftData<4, 4>(gl::floatToNormalized<4, uint16_t>(src->blue)) | + gl::shiftData<4, 0>(gl::floatToNormalized<4, uint16_t>(src->alpha)); +} + +void R4G4B4A4::average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2) +{ + dst->RGBA = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->RGBA), + gl::getShiftedData<4, 12>(src2->RGBA))) | + gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->RGBA), + gl::getShiftedData<4, 8>(src2->RGBA))) | + gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->RGBA), + gl::getShiftedData<4, 4>(src2->RGBA))) | + gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->RGBA), + gl::getShiftedData<4, 0>(src2->RGBA))); +} + +void A4R4G4B4::readColor(gl::ColorF *dst, const A4R4G4B4 *src) +{ + dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->ARGB)); + dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->ARGB)); + dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->ARGB)); + dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->ARGB)); +} + +void A4R4G4B4::writeColor(A4R4G4B4 *dst, const gl::ColorF *src) +{ + dst->ARGB = gl::shiftData<4, 12>(gl::floatToNormalized<4, uint16_t>(src->alpha)) | + gl::shiftData<4, 8>(gl::floatToNormalized<4, uint16_t>(src->red)) | + gl::shiftData<4, 4>(gl::floatToNormalized<4, uint16_t>(src->green)) | + gl::shiftData<4, 0>(gl::floatToNormalized<4, uint16_t>(src->blue)); +} + +void A4R4G4B4::average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2) +{ + dst->ARGB = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->ARGB), + gl::getShiftedData<4, 12>(src2->ARGB))) | + gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->ARGB), + gl::getShiftedData<4, 8>(src2->ARGB))) | + gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->ARGB), + gl::getShiftedData<4, 4>(src2->ARGB))) | + gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->ARGB), + gl::getShiftedData<4, 0>(src2->ARGB))); +} + +void R16::readColor(gl::ColorUI *dst, const R16 *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R16::readColor(gl::ColorF *dst, const R16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16::writeColor(R16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint16_t>(src->red); +} + +void R16::writeColor(R16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint16_t>(src->red); +} + +void R16::average(R16 *dst, const R16 *src1, const R16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R16G16::readColor(gl::ColorUI *dst, const R16G16 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R16G16::readColor(gl::ColorF *dst, const R16G16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16G16::writeColor(R16G16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint16_t>(src->red); + dst->G = static_cast<uint16_t>(src->green); +} + +void R16G16::writeColor(R16G16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint16_t>(src->red); + dst->G = gl::floatToNormalized<uint16_t>(src->green); +} + +void R16G16::average(R16G16 *dst, const R16G16 *src1, const R16G16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R16G16B16::readColor(gl::ColorUI *dst, const R16G16B16 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R16G16B16::readColor(gl::ColorF *dst, const R16G16B16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R16G16B16::writeColor(R16G16B16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint16_t>(src->red); + dst->G = static_cast<uint16_t>(src->green); + dst->B = static_cast<uint16_t>(src->blue); +} + +void R16G16B16::writeColor(R16G16B16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint16_t>(src->red); + dst->G = gl::floatToNormalized<uint16_t>(src->green); + dst->B = gl::floatToNormalized<uint16_t>(src->blue); +} + +void R16G16B16::average(R16G16B16 *dst, const R16G16B16 *src1, const R16G16B16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R16G16B16A16::readColor(gl::ColorUI *dst, const R16G16B16A16 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R16G16B16A16::readColor(gl::ColorF *dst, const R16G16B16A16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R16G16B16A16::writeColor(R16G16B16A16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint16_t>(src->red); + dst->G = static_cast<uint16_t>(src->green); + dst->B = static_cast<uint16_t>(src->blue); + dst->A = static_cast<uint16_t>(src->alpha); +} + +void R16G16B16A16::writeColor(R16G16B16A16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint16_t>(src->red); + dst->G = gl::floatToNormalized<uint16_t>(src->green); + dst->B = gl::floatToNormalized<uint16_t>(src->blue); + dst->A = gl::floatToNormalized<uint16_t>(src->alpha); +} + +void R16G16B16A16::average(R16G16B16A16 *dst, const R16G16B16A16 *src1, const R16G16B16A16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32::readColor(gl::ColorUI *dst, const R32 *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R32::readColor(gl::ColorF *dst, const R32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32::writeColor(R32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint32_t>(src->red); +} + +void R32::writeColor(R32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint32_t>(src->red); +} + +void R32::average(R32 *dst, const R32 *src1, const R32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R32G32::readColor(gl::ColorUI *dst, const R32G32 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R32G32::readColor(gl::ColorF *dst, const R32G32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32G32::writeColor(R32G32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint32_t>(src->red); + dst->G = static_cast<uint32_t>(src->green); +} + +void R32G32::writeColor(R32G32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint32_t>(src->red); + dst->G = gl::floatToNormalized<uint32_t>(src->green); +} + +void R32G32::average(R32G32 *dst, const R32G32 *src1, const R32G32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R32G32B32::readColor(gl::ColorUI *dst, const R32G32B32 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R32G32B32::readColor(gl::ColorF *dst, const R32G32B32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R32G32B32::writeColor(R32G32B32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint32_t>(src->red); + dst->G = static_cast<uint32_t>(src->green); + dst->B = static_cast<uint32_t>(src->blue); +} + +void R32G32B32::writeColor(R32G32B32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint32_t>(src->red); + dst->G = gl::floatToNormalized<uint32_t>(src->green); + dst->B = gl::floatToNormalized<uint32_t>(src->blue); +} + +void R32G32B32::average(R32G32B32 *dst, const R32G32B32 *src1, const R32G32B32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R32G32B32A32::readColor(gl::ColorUI *dst, const R32G32B32A32 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R32G32B32A32::readColor(gl::ColorF *dst, const R32G32B32A32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R32G32B32A32::writeColor(R32G32B32A32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint32_t>(src->red); + dst->G = static_cast<uint32_t>(src->green); + dst->B = static_cast<uint32_t>(src->blue); + dst->A = static_cast<uint32_t>(src->alpha); +} + +void R32G32B32A32::writeColor(R32G32B32A32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<uint32_t>(src->red); + dst->G = gl::floatToNormalized<uint32_t>(src->green); + dst->B = gl::floatToNormalized<uint32_t>(src->blue); + dst->A = gl::floatToNormalized<uint32_t>(src->alpha); +} + +void R32G32B32A32::average(R32G32B32A32 *dst, const R32G32B32A32 *src1, const R32G32B32A32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R8S::readColor(gl::ColorI *dst, const R8S *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R8S::readColor(gl::ColorF *dst, const R8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8S::writeColor(R8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int8_t>(src->red); +} + +void R8S::writeColor(R8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int8_t>(src->red); +} + +void R8S::average(R8S *dst, const R8S *src1, const R8S *src2) +{ + dst->R = static_cast<int8_t>(gl::average(src1->R, src2->R)); +} + +void R8G8S::readColor(gl::ColorI *dst, const R8G8S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R8G8S::readColor(gl::ColorF *dst, const R8G8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8G8S::writeColor(R8G8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int8_t>(src->red); + dst->G = static_cast<int8_t>(src->green); +} + +void R8G8S::writeColor(R8G8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int8_t>(src->red); + dst->G = gl::floatToNormalized<int8_t>(src->green); +} + +void R8G8S::average(R8G8S *dst, const R8G8S *src1, const R8G8S *src2) +{ + dst->R = static_cast<int8_t>(gl::average(src1->R, src2->R)); + dst->G = static_cast<int8_t>(gl::average(src1->G, src2->G)); +} + +void R8G8B8S::readColor(gl::ColorI *dst, const R8G8B8S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R8G8B8S::readColor(gl::ColorF *dst, const R8G8B8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R8G8B8S::writeColor(R8G8B8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int8_t>(src->red); + dst->G = static_cast<int8_t>(src->green); + dst->B = static_cast<int8_t>(src->blue); +} + +void R8G8B8S::writeColor(R8G8B8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int8_t>(src->red); + dst->G = gl::floatToNormalized<int8_t>(src->green); + dst->B = gl::floatToNormalized<int8_t>(src->blue); +} + +void R8G8B8S::average(R8G8B8S *dst, const R8G8B8S *src1, const R8G8B8S *src2) +{ + dst->R = static_cast<int8_t>(gl::average(src1->R, src2->R)); + dst->G = static_cast<int8_t>(gl::average(src1->G, src2->G)); + dst->B = static_cast<int8_t>(gl::average(src1->B, src2->B)); +} + +void R8G8B8A8S::readColor(gl::ColorI *dst, const R8G8B8A8S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R8G8B8A8S::readColor(gl::ColorF *dst, const R8G8B8A8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R8G8B8A8S::writeColor(R8G8B8A8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int8_t>(src->red); + dst->G = static_cast<int8_t>(src->green); + dst->B = static_cast<int8_t>(src->blue); + dst->A = static_cast<int8_t>(src->alpha); +} + +void R8G8B8A8S::writeColor(R8G8B8A8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int8_t>(src->red); + dst->G = gl::floatToNormalized<int8_t>(src->green); + dst->B = gl::floatToNormalized<int8_t>(src->blue); + dst->A = gl::floatToNormalized<int8_t>(src->alpha); +} + +void R8G8B8A8S::average(R8G8B8A8S *dst, const R8G8B8A8S *src1, const R8G8B8A8S *src2) +{ + dst->R = static_cast<int8_t>(gl::average(src1->R, src2->R)); + dst->G = static_cast<int8_t>(gl::average(src1->G, src2->G)); + dst->B = static_cast<int8_t>(gl::average(src1->B, src2->B)); + dst->A = static_cast<int8_t>(gl::average(src1->A, src2->A)); +} + +void R16S::readColor(gl::ColorI *dst, const R16S *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R16S::readColor(gl::ColorF *dst, const R16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16S::writeColor(R16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int16_t>(src->red); +} + +void R16S::writeColor(R16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int16_t>(src->red); +} + +void R16S::average(R16S *dst, const R16S *src1, const R16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R16G16S::readColor(gl::ColorI *dst, const R16G16S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R16G16S::readColor(gl::ColorF *dst, const R16G16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16G16S::writeColor(R16G16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int16_t>(src->red); + dst->G = static_cast<int16_t>(src->green); +} + +void R16G16S::writeColor(R16G16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int16_t>(src->red); + dst->G = gl::floatToNormalized<int16_t>(src->green); +} + +void R16G16S::average(R16G16S *dst, const R16G16S *src1, const R16G16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R16G16B16S::readColor(gl::ColorI *dst, const R16G16B16S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R16G16B16S::readColor(gl::ColorF *dst, const R16G16B16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R16G16B16S::writeColor(R16G16B16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int16_t>(src->red); + dst->G = static_cast<int16_t>(src->green); + dst->B = static_cast<int16_t>(src->blue); +} + +void R16G16B16S::writeColor(R16G16B16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int16_t>(src->red); + dst->G = gl::floatToNormalized<int16_t>(src->green); + dst->B = gl::floatToNormalized<int16_t>(src->blue); +} + +void R16G16B16S::average(R16G16B16S *dst, const R16G16B16S *src1, const R16G16B16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R16G16B16A16S::readColor(gl::ColorI *dst, const R16G16B16A16S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R16G16B16A16S::readColor(gl::ColorF *dst, const R16G16B16A16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R16G16B16A16S::writeColor(R16G16B16A16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int16_t>(src->red); + dst->G = static_cast<int16_t>(src->green); + dst->B = static_cast<int16_t>(src->blue); + dst->A = static_cast<int16_t>(src->alpha); +} + +void R16G16B16A16S::writeColor(R16G16B16A16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int16_t>(src->red); + dst->G = gl::floatToNormalized<int16_t>(src->green); + dst->B = gl::floatToNormalized<int16_t>(src->blue); + dst->A = gl::floatToNormalized<int16_t>(src->alpha); +} + +void R16G16B16A16S::average(R16G16B16A16S *dst, + const R16G16B16A16S *src1, + const R16G16B16A16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32S::readColor(gl::ColorI *dst, const R32S *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R32S::readColor(gl::ColorF *dst, const R32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32S::writeColor(R32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int32_t>(src->red); +} + +void R32S::writeColor(R32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int32_t>(src->red); +} + +void R32S::average(R32S *dst, const R32S *src1, const R32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R32G32S::readColor(gl::ColorI *dst, const R32G32S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R32G32S::readColor(gl::ColorF *dst, const R32G32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32G32S::writeColor(R32G32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int32_t>(src->red); + dst->G = static_cast<int32_t>(src->green); +} + +void R32G32S::writeColor(R32G32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int32_t>(src->red); + dst->G = gl::floatToNormalized<int32_t>(src->green); +} + +void R32G32S::average(R32G32S *dst, const R32G32S *src1, const R32G32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R32G32B32S::readColor(gl::ColorI *dst, const R32G32B32S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R32G32B32S::readColor(gl::ColorF *dst, const R32G32B32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R32G32B32S::writeColor(R32G32B32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int32_t>(src->red); + dst->G = static_cast<int32_t>(src->green); + dst->B = static_cast<int32_t>(src->blue); +} + +void R32G32B32S::writeColor(R32G32B32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int32_t>(src->red); + dst->G = gl::floatToNormalized<int32_t>(src->green); + dst->B = gl::floatToNormalized<int32_t>(src->blue); +} + +void R32G32B32S::average(R32G32B32S *dst, const R32G32B32S *src1, const R32G32B32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R32G32B32A32S::readColor(gl::ColorI *dst, const R32G32B32A32S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R32G32B32A32S::readColor(gl::ColorF *dst, const R32G32B32A32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R32G32B32A32S::writeColor(R32G32B32A32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast<int32_t>(src->red); + dst->G = static_cast<int32_t>(src->green); + dst->B = static_cast<int32_t>(src->blue); + dst->A = static_cast<int32_t>(src->alpha); +} + +void R32G32B32A32S::writeColor(R32G32B32A32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<int32_t>(src->red); + dst->G = gl::floatToNormalized<int32_t>(src->green); + dst->B = gl::floatToNormalized<int32_t>(src->blue); + dst->A = gl::floatToNormalized<int32_t>(src->alpha); +} + +void R32G32B32A32S::average(R32G32B32A32S *dst, + const R32G32B32A32S *src1, + const R32G32B32A32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void A16B16G16R16F::readColor(gl::ColorF *dst, const A16B16G16R16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = gl::float16ToFloat32(src->A); +} + +void A16B16G16R16F::writeColor(A16B16G16R16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); + dst->A = gl::float32ToFloat16(src->alpha); +} + +void A16B16G16R16F::average(A16B16G16R16F *dst, + const A16B16G16R16F *src1, + const A16B16G16R16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void R16G16B16A16F::readColor(gl::ColorF *dst, const R16G16B16A16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = gl::float16ToFloat32(src->A); +} + +void R16G16B16A16F::writeColor(R16G16B16A16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); + dst->A = gl::float32ToFloat16(src->alpha); +} + +void R16G16B16A16F::average(R16G16B16A16F *dst, + const R16G16B16A16F *src1, + const R16G16B16A16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void R16F::readColor(gl::ColorF *dst, const R16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16F::writeColor(R16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); +} + +void R16F::average(R16F *dst, const R16F *src1, const R16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); +} + +void A16F::readColor(gl::ColorF *dst, const A16F *src) +{ + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = gl::float16ToFloat32(src->A); +} + +void A16F::writeColor(A16F *dst, const gl::ColorF *src) +{ + dst->A = gl::float32ToFloat16(src->alpha); +} + +void A16F::average(A16F *dst, const A16F *src1, const A16F *src2) +{ + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void L16F::readColor(gl::ColorF *dst, const L16F *src) +{ + float lum = gl::float16ToFloat32(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = 1.0f; +} + +void L16F::writeColor(L16F *dst, const gl::ColorF *src) +{ + dst->L = gl::float32ToFloat16(src->red); +} + +void L16F::average(L16F *dst, const L16F *src1, const L16F *src2) +{ + dst->L = gl::averageHalfFloat(src1->L, src2->L); +} + +void L16A16F::readColor(gl::ColorF *dst, const L16A16F *src) +{ + float lum = gl::float16ToFloat32(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::float16ToFloat32(src->A); +} + +void L16A16F::writeColor(L16A16F *dst, const gl::ColorF *src) +{ + dst->L = gl::float32ToFloat16(src->red); + dst->A = gl::float32ToFloat16(src->alpha); +} + +void L16A16F::average(L16A16F *dst, const L16A16F *src1, const L16A16F *src2) +{ + dst->L = gl::averageHalfFloat(src1->L, src2->L); + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void R16G16F::readColor(gl::ColorF *dst, const R16G16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16G16F::writeColor(R16G16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); +} + +void R16G16F::average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); +} + +void R16G16B16F::readColor(gl::ColorF *dst, const R16G16B16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = 1.0f; +} + +void R16G16B16F::writeColor(R16G16B16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); +} + +void R16G16B16F::average(R16G16B16F *dst, const R16G16B16F *src1, const R16G16B16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); +} + +void A32B32G32R32F::readColor(gl::ColorF *dst, const A32B32G32R32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void A32B32G32R32F::writeColor(A32B32G32R32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; + dst->A = src->alpha; +} + +void A32B32G32R32F::average(A32B32G32R32F *dst, + const A32B32G32R32F *src1, + const A32B32G32R32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32G32B32A32F::readColor(gl::ColorF *dst, const R32G32B32A32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R32G32B32A32F::writeColor(R32G32B32A32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; + dst->A = src->alpha; +} + +void R32G32B32A32F::average(R32G32B32A32F *dst, + const R32G32B32A32F *src1, + const R32G32B32A32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32F::readColor(gl::ColorF *dst, const R32F *src) +{ + dst->red = src->R; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32F::writeColor(R32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; +} + +void R32F::average(R32F *dst, const R32F *src1, const R32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void A32F::readColor(gl::ColorF *dst, const A32F *src) +{ + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = src->A; +} + +void A32F::writeColor(A32F *dst, const gl::ColorF *src) +{ + dst->A = src->alpha; +} + +void A32F::average(A32F *dst, const A32F *src1, const A32F *src2) +{ + dst->A = gl::average(src1->A, src2->A); +} + +void L32F::readColor(gl::ColorF *dst, const L32F *src) +{ + dst->red = src->L; + dst->green = src->L; + dst->blue = src->L; + dst->alpha = 1.0f; +} + +void L32F::writeColor(L32F *dst, const gl::ColorF *src) +{ + dst->L = src->red; +} + +void L32F::average(L32F *dst, const L32F *src1, const L32F *src2) +{ + dst->L = gl::average(src1->L, src2->L); +} + +void L32A32F::readColor(gl::ColorF *dst, const L32A32F *src) +{ + dst->red = src->L; + dst->green = src->L; + dst->blue = src->L; + dst->alpha = src->A; +} + +void L32A32F::writeColor(L32A32F *dst, const gl::ColorF *src) +{ + dst->L = src->red; + dst->A = src->alpha; +} + +void L32A32F::average(L32A32F *dst, const L32A32F *src1, const L32A32F *src2) +{ + dst->L = gl::average(src1->L, src2->L); + dst->A = gl::average(src1->A, src2->A); +} + +void R32G32F::readColor(gl::ColorF *dst, const R32G32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32G32F::writeColor(R32G32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; +} + +void R32G32F::average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R32G32B32F::readColor(gl::ColorF *dst, const R32G32B32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1.0f; +} + +void R32G32B32F::writeColor(R32G32B32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; +} + +void R32G32B32F::average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R10G10B10A2::readColor(gl::ColorUI *dst, const R10G10B10A2 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R10G10B10A2::readColor(gl::ColorF *dst, const R10G10B10A2 *src) +{ + dst->red = gl::normalizedToFloat<10>(src->R); + dst->green = gl::normalizedToFloat<10>(src->G); + dst->blue = gl::normalizedToFloat<10>(src->B); + dst->alpha = gl::normalizedToFloat<2>(src->A); +} + +void R10G10B10A2::writeColor(R10G10B10A2 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast<uint32_t>(src->red); + dst->G = static_cast<uint32_t>(src->green); + dst->B = static_cast<uint32_t>(src->blue); + dst->A = static_cast<uint32_t>(src->alpha); +} + +void R10G10B10A2::writeColor(R10G10B10A2 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<10, uint32_t>(src->red); + dst->G = gl::floatToNormalized<10, uint32_t>(src->green); + dst->B = gl::floatToNormalized<10, uint32_t>(src->blue); + dst->A = gl::floatToNormalized<2, uint32_t>(src->alpha); +} + +void R10G10B10A2::average(R10G10B10A2 *dst, const R10G10B10A2 *src1, const R10G10B10A2 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R9G9B9E5::readColor(gl::ColorF *dst, const R9G9B9E5 *src) +{ + gl::convert999E5toRGBFloats(gl::bitCast<uint32_t>(*src), &dst->red, &dst->green, &dst->blue); + dst->alpha = 1.0f; +} + +void R9G9B9E5::writeColor(R9G9B9E5 *dst, const gl::ColorF *src) +{ + *reinterpret_cast<uint32_t *>(dst) = + gl::convertRGBFloatsTo999E5(src->red, src->green, src->blue); +} + +void R9G9B9E5::average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2) +{ + float r1, g1, b1; + gl::convert999E5toRGBFloats(*reinterpret_cast<const uint32_t *>(src1), &r1, &g1, &b1); + + float r2, g2, b2; + gl::convert999E5toRGBFloats(*reinterpret_cast<const uint32_t *>(src2), &r2, &g2, &b2); + + *reinterpret_cast<uint32_t *>(dst) = + gl::convertRGBFloatsTo999E5(gl::average(r1, r2), gl::average(g1, g2), gl::average(b1, b2)); +} + +void R11G11B10F::readColor(gl::ColorF *dst, const R11G11B10F *src) +{ + dst->red = gl::float11ToFloat32(src->R); + dst->green = gl::float11ToFloat32(src->G); + dst->blue = gl::float10ToFloat32(src->B); + dst->alpha = 1.0f; +} + +void R11G11B10F::writeColor(R11G11B10F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat11(src->red); + dst->G = gl::float32ToFloat11(src->green); + dst->B = gl::float32ToFloat10(src->blue); +} + +void R11G11B10F::average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B10F *src2) +{ + dst->R = gl::averageFloat11(src1->R, src2->R); + dst->G = gl::averageFloat11(src1->G, src2->G); + dst->B = gl::averageFloat10(src1->B, src2->B); +} + +} // namespace angle diff --git a/chromium/third_party/angle/src/image_util/imageformats.h b/chromium/third_party/angle/src/image_util/imageformats.h new file mode 100644 index 00000000000..b4ff04482f8 --- /dev/null +++ b/chromium/third_party/angle/src/image_util/imageformats.h @@ -0,0 +1,688 @@ +// +// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// imageformats.h: Defines image format types with functions for mip generation +// and copying. + +#ifndef IMAGEUTIL_IMAGEFORMATS_H_ +#define IMAGEUTIL_IMAGEFORMATS_H_ + +#include "common/Color.h" + +#include <cstdint> + +namespace angle +{ + +// Several structures share functionality for reading, writing or mipmapping but the layout +// must match the texture format which the structure represents. If collapsing or typedefing +// structs in this header, make sure the functionality and memory layout is exactly the same. + +struct L8 +{ + uint8_t L; + + static void readColor(gl::ColorF *dst, const L8 *src); + static void writeColor(L8 *dst, const gl::ColorF *src); + static void average(L8 *dst, const L8 *src1, const L8 *src2); +}; + +struct R8 +{ + uint8_t R; + + static void readColor(gl::ColorF *dst, const R8 *src); + static void readColor(gl::ColorUI *dst, const R8 *src); + static void writeColor(R8 *dst, const gl::ColorF *src); + static void writeColor(R8 *dst, const gl::ColorUI *src); + static void average(R8 *dst, const R8 *src1, const R8 *src2); +}; + +struct A8 +{ + uint8_t A; + + static void readColor(gl::ColorF *dst, const A8 *src); + static void writeColor(A8 *dst, const gl::ColorF *src); + static void average(A8 *dst, const A8 *src1, const A8 *src2); +}; + +struct L8A8 +{ + uint8_t L; + uint8_t A; + + static void readColor(gl::ColorF *dst, const L8A8 *src); + static void writeColor(L8A8 *dst, const gl::ColorF *src); + static void average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2); +}; + +struct A8L8 +{ + uint8_t A; + uint8_t L; + + static void readColor(gl::ColorF *dst, const A8L8 *src); + static void writeColor(A8L8 *dst, const gl::ColorF *src); + static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2); +}; + +struct R8G8 +{ + uint8_t R; + uint8_t G; + + static void readColor(gl::ColorF *dst, const R8G8 *src); + static void readColor(gl::ColorUI *dst, const R8G8 *src); + static void writeColor(R8G8 *dst, const gl::ColorF *src); + static void writeColor(R8G8 *dst, const gl::ColorUI *src); + static void average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2); +}; + +struct R8G8B8 +{ + uint8_t R; + uint8_t G; + uint8_t B; + + static void readColor(gl::ColorF *dst, const R8G8B8 *src); + static void readColor(gl::ColorUI *dst, const R8G8B8 *src); + static void writeColor(R8G8B8 *dst, const gl::ColorF *src); + static void writeColor(R8G8B8 *dst, const gl::ColorUI *src); + static void average(R8G8B8 *dst, const R8G8B8 *src1, const R8G8B8 *src2); +}; + +struct B8G8R8 +{ + uint8_t B; + uint8_t G; + uint8_t R; + + static void readColor(gl::ColorF *dst, const B8G8R8 *src); + static void readColor(gl::ColorUI *dst, const B8G8R8 *src); + static void writeColor(B8G8R8 *dst, const gl::ColorF *src); + static void writeColor(B8G8R8 *dst, const gl::ColorUI *src); + static void average(B8G8R8 *dst, const B8G8R8 *src1, const B8G8R8 *src2); +}; + +struct R5G6B5 +{ + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the + // most significant bits of the bitfield, and successive component occupying progressively less + // significant locations" + uint16_t RGB; + + static void readColor(gl::ColorF *dst, const R5G6B5 *src); + static void writeColor(R5G6B5 *dst, const gl::ColorF *src); + static void average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2); +}; + +struct B5G6R5 +{ + uint16_t BGR; + + static void readColor(gl::ColorF *dst, const B5G6R5 *src); + static void writeColor(B5G6R5 *dst, const gl::ColorF *src); + static void average(B5G6R5 *dst, const B5G6R5 *src1, const B5G6R5 *src2); +}; + +struct A8R8G8B8 +{ + uint8_t A; + uint8_t R; + uint8_t G; + uint8_t B; + + static void readColor(gl::ColorF *dst, const A8R8G8B8 *src); + static void readColor(gl::ColorUI *dst, const A8R8G8B8 *src); + static void writeColor(A8R8G8B8 *dst, const gl::ColorF *src); + static void writeColor(A8R8G8B8 *dst, const gl::ColorUI *src); + static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2); +}; + +struct R8G8B8A8 +{ + uint8_t R; + uint8_t G; + uint8_t B; + uint8_t A; + + static void readColor(gl::ColorF *dst, const R8G8B8A8 *src); + static void readColor(gl::ColorUI *dst, const R8G8B8A8 *src); + static void writeColor(R8G8B8A8 *dst, const gl::ColorF *src); + static void writeColor(R8G8B8A8 *dst, const gl::ColorUI *src); + static void average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2); +}; + +struct B8G8R8A8 +{ + uint8_t B; + uint8_t G; + uint8_t R; + uint8_t A; + + static void readColor(gl::ColorF *dst, const B8G8R8A8 *src); + static void readColor(gl::ColorUI *dst, const B8G8R8A8 *src); + static void writeColor(B8G8R8A8 *dst, const gl::ColorF *src); + static void writeColor(B8G8R8A8 *dst, const gl::ColorUI *src); + static void average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2); +}; + +struct B8G8R8X8 +{ + uint8_t B; + uint8_t G; + uint8_t R; + uint8_t X; + + static void readColor(gl::ColorF *dst, const B8G8R8X8 *src); + static void readColor(gl::ColorUI *dst, const B8G8R8X8 *src); + static void writeColor(B8G8R8X8 *dst, const gl::ColorF *src); + static void writeColor(B8G8R8X8 *dst, const gl::ColorUI *src); + static void average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2); +}; + +struct A1R5G5B5 +{ + uint16_t ARGB; + + static void readColor(gl::ColorF *dst, const A1R5G5B5 *src); + static void writeColor(A1R5G5B5 *dst, const gl::ColorF *src); + static void average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2); +}; + +struct R5G5B5A1 +{ + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the + // most significant + // bits of the bitfield, and successive component occupying progressively less significant + // locations" + uint16_t RGBA; + + static void readColor(gl::ColorF *dst, const R5G5B5A1 *src); + static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src); + static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2); +}; + +struct R4G4B4A4 +{ + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the + // most significant + // bits of the bitfield, and successive component occupying progressively less significant + // locations" + uint16_t RGBA; + + static void readColor(gl::ColorF *dst, const R4G4B4A4 *src); + static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src); + static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2); +}; + +struct A4R4G4B4 +{ + uint16_t ARGB; + + static void readColor(gl::ColorF *dst, const A4R4G4B4 *src); + static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src); + static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2); +}; + +struct R16 +{ + uint16_t R; + + static void readColor(gl::ColorF *dst, const R16 *src); + static void readColor(gl::ColorUI *dst, const R16 *src); + static void writeColor(R16 *dst, const gl::ColorF *src); + static void writeColor(R16 *dst, const gl::ColorUI *src); + static void average(R16 *dst, const R16 *src1, const R16 *src2); +}; + +struct R16G16 +{ + uint16_t R; + uint16_t G; + + static void readColor(gl::ColorF *dst, const R16G16 *src); + static void readColor(gl::ColorUI *dst, const R16G16 *src); + static void writeColor(R16G16 *dst, const gl::ColorF *src); + static void writeColor(R16G16 *dst, const gl::ColorUI *src); + static void average(R16G16 *dst, const R16G16 *src1, const R16G16 *src2); +}; + +struct R16G16B16 +{ + uint16_t R; + uint16_t G; + uint16_t B; + + static void readColor(gl::ColorF *dst, const R16G16B16 *src); + static void readColor(gl::ColorUI *dst, const R16G16B16 *src); + static void writeColor(R16G16B16 *dst, const gl::ColorF *src); + static void writeColor(R16G16B16 *dst, const gl::ColorUI *src); + static void average(R16G16B16 *dst, const R16G16B16 *src1, const R16G16B16 *src2); +}; + +struct R16G16B16A16 +{ + uint16_t R; + uint16_t G; + uint16_t B; + uint16_t A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16 *src); + static void readColor(gl::ColorUI *dst, const R16G16B16A16 *src); + static void writeColor(R16G16B16A16 *dst, const gl::ColorF *src); + static void writeColor(R16G16B16A16 *dst, const gl::ColorUI *src); + static void average(R16G16B16A16 *dst, const R16G16B16A16 *src1, const R16G16B16A16 *src2); +}; + +struct R32 +{ + uint32_t R; + + static void readColor(gl::ColorF *dst, const R32 *src); + static void readColor(gl::ColorUI *dst, const R32 *src); + static void writeColor(R32 *dst, const gl::ColorF *src); + static void writeColor(R32 *dst, const gl::ColorUI *src); + static void average(R32 *dst, const R32 *src1, const R32 *src2); +}; + +struct R32G32 +{ + uint32_t R; + uint32_t G; + + static void readColor(gl::ColorF *dst, const R32G32 *src); + static void readColor(gl::ColorUI *dst, const R32G32 *src); + static void writeColor(R32G32 *dst, const gl::ColorF *src); + static void writeColor(R32G32 *dst, const gl::ColorUI *src); + static void average(R32G32 *dst, const R32G32 *src1, const R32G32 *src2); +}; + +struct R32G32B32 +{ + uint32_t R; + uint32_t G; + uint32_t B; + + static void readColor(gl::ColorF *dst, const R32G32B32 *src); + static void readColor(gl::ColorUI *dst, const R32G32B32 *src); + static void writeColor(R32G32B32 *dst, const gl::ColorF *src); + static void writeColor(R32G32B32 *dst, const gl::ColorUI *src); + static void average(R32G32B32 *dst, const R32G32B32 *src1, const R32G32B32 *src2); +}; + +struct R32G32B32A32 +{ + uint32_t R; + uint32_t G; + uint32_t B; + uint32_t A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32 *src); + static void readColor(gl::ColorUI *dst, const R32G32B32A32 *src); + static void writeColor(R32G32B32A32 *dst, const gl::ColorF *src); + static void writeColor(R32G32B32A32 *dst, const gl::ColorUI *src); + static void average(R32G32B32A32 *dst, const R32G32B32A32 *src1, const R32G32B32A32 *src2); +}; + +struct R8S +{ + int8_t R; + + static void readColor(gl::ColorF *dst, const R8S *src); + static void readColor(gl::ColorI *dst, const R8S *src); + static void writeColor(R8S *dst, const gl::ColorF *src); + static void writeColor(R8S *dst, const gl::ColorI *src); + static void average(R8S *dst, const R8S *src1, const R8S *src2); +}; + +struct R8G8S +{ + int8_t R; + int8_t G; + + static void readColor(gl::ColorF *dst, const R8G8S *src); + static void readColor(gl::ColorI *dst, const R8G8S *src); + static void writeColor(R8G8S *dst, const gl::ColorF *src); + static void writeColor(R8G8S *dst, const gl::ColorI *src); + static void average(R8G8S *dst, const R8G8S *src1, const R8G8S *src2); +}; + +struct R8G8B8S +{ + int8_t R; + int8_t G; + int8_t B; + + static void readColor(gl::ColorF *dst, const R8G8B8S *src); + static void readColor(gl::ColorI *dst, const R8G8B8S *src); + static void writeColor(R8G8B8S *dst, const gl::ColorF *src); + static void writeColor(R8G8B8S *dst, const gl::ColorI *src); + static void average(R8G8B8S *dst, const R8G8B8S *src1, const R8G8B8S *src2); +}; + +struct R8G8B8A8S +{ + int8_t R; + int8_t G; + int8_t B; + int8_t A; + + static void readColor(gl::ColorF *dst, const R8G8B8A8S *src); + static void readColor(gl::ColorI *dst, const R8G8B8A8S *src); + static void writeColor(R8G8B8A8S *dst, const gl::ColorF *src); + static void writeColor(R8G8B8A8S *dst, const gl::ColorI *src); + static void average(R8G8B8A8S *dst, const R8G8B8A8S *src1, const R8G8B8A8S *src2); +}; + +struct R16S +{ + int16_t R; + + static void readColor(gl::ColorF *dst, const R16S *src); + static void readColor(gl::ColorI *dst, const R16S *src); + static void writeColor(R16S *dst, const gl::ColorF *src); + static void writeColor(R16S *dst, const gl::ColorI *src); + static void average(R16S *dst, const R16S *src1, const R16S *src2); +}; + +struct R16G16S +{ + int16_t R; + int16_t G; + + static void readColor(gl::ColorF *dst, const R16G16S *src); + static void readColor(gl::ColorI *dst, const R16G16S *src); + static void writeColor(R16G16S *dst, const gl::ColorF *src); + static void writeColor(R16G16S *dst, const gl::ColorI *src); + static void average(R16G16S *dst, const R16G16S *src1, const R16G16S *src2); +}; + +struct R16G16B16S +{ + int16_t R; + int16_t G; + int16_t B; + + static void readColor(gl::ColorF *dst, const R16G16B16S *src); + static void readColor(gl::ColorI *dst, const R16G16B16S *src); + static void writeColor(R16G16B16S *dst, const gl::ColorF *src); + static void writeColor(R16G16B16S *dst, const gl::ColorI *src); + static void average(R16G16B16S *dst, const R16G16B16S *src1, const R16G16B16S *src2); +}; + +struct R16G16B16A16S +{ + int16_t R; + int16_t G; + int16_t B; + int16_t A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16S *src); + static void readColor(gl::ColorI *dst, const R16G16B16A16S *src); + static void writeColor(R16G16B16A16S *dst, const gl::ColorF *src); + static void writeColor(R16G16B16A16S *dst, const gl::ColorI *src); + static void average(R16G16B16A16S *dst, const R16G16B16A16S *src1, const R16G16B16A16S *src2); +}; + +struct R32S +{ + int32_t R; + + static void readColor(gl::ColorF *dst, const R32S *src); + static void readColor(gl::ColorI *dst, const R32S *src); + static void writeColor(R32S *dst, const gl::ColorF *src); + static void writeColor(R32S *dst, const gl::ColorI *src); + static void average(R32S *dst, const R32S *src1, const R32S *src2); +}; + +struct R32G32S +{ + int32_t R; + int32_t G; + + static void readColor(gl::ColorF *dst, const R32G32S *src); + static void readColor(gl::ColorI *dst, const R32G32S *src); + static void writeColor(R32G32S *dst, const gl::ColorF *src); + static void writeColor(R32G32S *dst, const gl::ColorI *src); + static void average(R32G32S *dst, const R32G32S *src1, const R32G32S *src2); +}; + +struct R32G32B32S +{ + int32_t R; + int32_t G; + int32_t B; + + static void readColor(gl::ColorF *dst, const R32G32B32S *src); + static void readColor(gl::ColorI *dst, const R32G32B32S *src); + static void writeColor(R32G32B32S *dst, const gl::ColorF *src); + static void writeColor(R32G32B32S *dst, const gl::ColorI *src); + static void average(R32G32B32S *dst, const R32G32B32S *src1, const R32G32B32S *src2); +}; + +struct R32G32B32A32S +{ + int32_t R; + int32_t G; + int32_t B; + int32_t A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32S *src); + static void readColor(gl::ColorI *dst, const R32G32B32A32S *src); + static void writeColor(R32G32B32A32S *dst, const gl::ColorF *src); + static void writeColor(R32G32B32A32S *dst, const gl::ColorI *src); + static void average(R32G32B32A32S *dst, const R32G32B32A32S *src1, const R32G32B32A32S *src2); +}; + +struct A16B16G16R16F +{ + uint16_t A; + uint16_t R; + uint16_t G; + uint16_t B; + + static void readColor(gl::ColorF *dst, const A16B16G16R16F *src); + static void writeColor(A16B16G16R16F *dst, const gl::ColorF *src); + static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2); +}; + +struct R16G16B16A16F +{ + uint16_t R; + uint16_t G; + uint16_t B; + uint16_t A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16F *src); + static void writeColor(R16G16B16A16F *dst, const gl::ColorF *src); + static void average(R16G16B16A16F *dst, const R16G16B16A16F *src1, const R16G16B16A16F *src2); +}; + +struct R16F +{ + uint16_t R; + + static void readColor(gl::ColorF *dst, const R16F *src); + static void writeColor(R16F *dst, const gl::ColorF *src); + static void average(R16F *dst, const R16F *src1, const R16F *src2); +}; + +struct A16F +{ + uint16_t A; + + static void readColor(gl::ColorF *dst, const A16F *src); + static void writeColor(A16F *dst, const gl::ColorF *src); + static void average(A16F *dst, const A16F *src1, const A16F *src2); +}; + +struct L16F +{ + uint16_t L; + + static void readColor(gl::ColorF *dst, const L16F *src); + static void writeColor(L16F *dst, const gl::ColorF *src); + static void average(L16F *dst, const L16F *src1, const L16F *src2); +}; + +struct L16A16F +{ + uint16_t L; + uint16_t A; + + static void readColor(gl::ColorF *dst, const L16A16F *src); + static void writeColor(L16A16F *dst, const gl::ColorF *src); + static void average(L16A16F *dst, const L16A16F *src1, const L16A16F *src2); +}; + +struct R16G16F +{ + uint16_t R; + uint16_t G; + + static void readColor(gl::ColorF *dst, const R16G16F *src); + static void writeColor(R16G16F *dst, const gl::ColorF *src); + static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2); +}; + +struct R16G16B16F +{ + uint16_t R; + uint16_t G; + uint16_t B; + + static void readColor(gl::ColorF *dst, const R16G16B16F *src); + static void writeColor(R16G16B16F *dst, const gl::ColorF *src); + static void average(R16G16B16F *dst, const R16G16B16F *src1, const R16G16B16F *src2); +}; + +struct A32B32G32R32F +{ + float A; + float R; + float G; + float B; + + static void readColor(gl::ColorF *dst, const A32B32G32R32F *src); + static void writeColor(A32B32G32R32F *dst, const gl::ColorF *src); + static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2); +}; + +struct R32G32B32A32F +{ + float R; + float G; + float B; + float A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32F *src); + static void writeColor(R32G32B32A32F *dst, const gl::ColorF *src); + static void average(R32G32B32A32F *dst, const R32G32B32A32F *src1, const R32G32B32A32F *src2); +}; + +struct R32F +{ + float R; + + static void readColor(gl::ColorF *dst, const R32F *src); + static void writeColor(R32F *dst, const gl::ColorF *src); + static void average(R32F *dst, const R32F *src1, const R32F *src2); +}; + +struct A32F +{ + float A; + + static void readColor(gl::ColorF *dst, const A32F *src); + static void writeColor(A32F *dst, const gl::ColorF *src); + static void average(A32F *dst, const A32F *src1, const A32F *src2); +}; + +struct L32F +{ + float L; + + static void readColor(gl::ColorF *dst, const L32F *src); + static void writeColor(L32F *dst, const gl::ColorF *src); + static void average(L32F *dst, const L32F *src1, const L32F *src2); +}; + +struct L32A32F +{ + float L; + float A; + + static void readColor(gl::ColorF *dst, const L32A32F *src); + static void writeColor(L32A32F *dst, const gl::ColorF *src); + static void average(L32A32F *dst, const L32A32F *src1, const L32A32F *src2); +}; + +struct R32G32F +{ + float R; + float G; + + static void readColor(gl::ColorF *dst, const R32G32F *src); + static void writeColor(R32G32F *dst, const gl::ColorF *src); + static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2); +}; + +struct R32G32B32F +{ + float R; + float G; + float B; + + static void readColor(gl::ColorF *dst, const R32G32B32F *src); + static void writeColor(R32G32B32F *dst, const gl::ColorF *src); + static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2); +}; + +struct R10G10B10A2 +{ + uint32_t R : 10; + uint32_t G : 10; + uint32_t B : 10; + uint32_t A : 2; + + static void readColor(gl::ColorF *dst, const R10G10B10A2 *src); + static void readColor(gl::ColorUI *dst, const R10G10B10A2 *src); + static void writeColor(R10G10B10A2 *dst, const gl::ColorF *src); + static void writeColor(R10G10B10A2 *dst, const gl::ColorUI *src); + static void average(R10G10B10A2 *dst, const R10G10B10A2 *src1, const R10G10B10A2 *src2); +}; +static_assert(sizeof(R10G10B10A2) == 4, "R10G10B10A2 struct not 32-bits."); + +struct R9G9B9E5 +{ + uint32_t R : 9; + uint32_t G : 9; + uint32_t B : 9; + uint32_t E : 5; + + static void readColor(gl::ColorF *dst, const R9G9B9E5 *src); + static void writeColor(R9G9B9E5 *dst, const gl::ColorF *src); + static void average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2); +}; +static_assert(sizeof(R9G9B9E5) == 4, "R9G9B9E5 struct not 32-bits."); + +struct R11G11B10F +{ + uint32_t R : 11; + uint32_t G : 11; + uint32_t B : 10; + + static void readColor(gl::ColorF *dst, const R11G11B10F *src); + static void writeColor(R11G11B10F *dst, const gl::ColorF *src); + static void average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B10F *src2); +}; +static_assert(sizeof(R11G11B10F) == 4, "R11G11B10F struct not 32-bits."); + +} // namespace angle + +#endif // IMAGEUTIL_IMAGEFORMATS_H_ diff --git a/chromium/third_party/angle/src/image_util/loadimage.cpp b/chromium/third_party/angle/src/image_util/loadimage.cpp new file mode 100644 index 00000000000..56ad3b32e3a --- /dev/null +++ b/chromium/third_party/angle/src/image_util/loadimage.cpp @@ -0,0 +1,1323 @@ +// +// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// angle_loadimage.cpp: Defines image loading functions. + +#include "image_util/loadimage.h" + +#include "common/mathutil.h" +#include "common/platform.h" +#include "image_util/imageformats.h" + +namespace angle +{ + +void LoadA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ +#if defined(ANGLE_USE_SSE) + if (gl::supportsSSE2()) + { + __m128i zeroWide = _mm_setzero_si128(); + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, + outputDepthPitch); + + size_t x = 0; + + // Make output writes aligned + for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++) + { + dest[x] = static_cast<uint32_t>(source[x]) << 24; + } + + for (; x + 7 < width; x += 8) + { + __m128i sourceData = + _mm_loadl_epi64(reinterpret_cast<const __m128i *>(&source[x])); + // Interleave each byte to 16bit, make the lower byte to zero + sourceData = _mm_unpacklo_epi8(zeroWide, sourceData); + // Interleave each 16bit to 32bit, make the lower 16bit to zero + __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData); + __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData); + + _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), lo); + _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x + 4]), hi); + } + + // Handle the remainder + for (; x < width; x++) + { + dest[x] = static_cast<uint32_t>(source[x]) << 24; + } + } + } + + return; + } +#endif + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = static_cast<uint32_t>(source[x]) << 24; + } + } + } +} + +void LoadA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + // Same as loading to RGBA + LoadA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch); +} + +void LoadA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0.0f; + dest[4 * x + 1] = 0.0f; + dest[4 * x + 2] = 0.0f; + dest[4 * x + 3] = source[x]; + } + } + } +} + +void LoadA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0; + dest[4 * x + 1] = 0; + dest[4 * x + 2] = 0; + dest[4 * x + 3] = source[x]; + } + } + } +} + +void LoadL8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint8_t sourceVal = source[x]; + dest[4 * x + 0] = sourceVal; + dest[4 * x + 1] = sourceVal; + dest[4 * x + 2] = sourceVal; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadL8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + // Same as loading to RGBA + LoadL8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch); +} + +void LoadL32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x]; + dest[4 * x + 1] = source[x]; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = 1.0f; + } + } + } +} + +void LoadL16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x]; + dest[4 * x + 1] = source[x]; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = gl::Float16One; + } + } + } +} + +void LoadLA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2 * x + 0]; + dest[4 * x + 1] = source[2 * x + 0]; + dest[4 * x + 2] = source[2 * x + 0]; + dest[4 * x + 3] = source[2 * x + 1]; + } + } + } +} + +void LoadLA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + // Same as loading to RGBA + LoadLA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch); +} + +void LoadLA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2 * x + 0]; + dest[4 * x + 1] = source[2 * x + 0]; + dest[4 * x + 2] = source[2 * x + 0]; + dest[4 * x + 3] = source[2 * x + 1]; + } + } + } +} + +void LoadLA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2 * x + 0]; + dest[4 * x + 1] = source[2 * x + 0]; + dest[4 * x + 2] = source[2 * x + 0]; + dest[4 * x + 3] = source[2 * x + 1]; + } + } + } +} + +void LoadRGB8ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint8_t r8 = source[x * 3 + 0]; + uint8_t g8 = source[x * 3 + 1]; + uint8_t b8 = source[x * 3 + 2]; + auto r5 = static_cast<uint16_t>(r8 >> 3); + auto g6 = static_cast<uint16_t>(g8 >> 2); + auto b5 = static_cast<uint16_t>(b8 >> 3); + dest[x] = (r5 << 11) | (g6 << 5) | b5; + } + } + } +} + +void LoadRGB565ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + // The GL type RGB is packed with with red in the MSB, while the D3D11 type BGR + // is packed with red in the LSB + auto rgb = source[x]; + uint16_t r5 = gl::getShiftedData<5, 11>(rgb); + uint16_t g6 = gl::getShiftedData<6, 5>(rgb); + uint16_t b5 = gl::getShiftedData<5, 0>(rgb); + dest[x] = (r5 << 11) | (g6 << 5) | b5; + } + } + } +} + +void LoadRGB8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x * 3 + 2]; + dest[4 * x + 1] = source[x * 3 + 1]; + dest[4 * x + 2] = source[x * 3 + 0]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadRG8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0x00; + dest[4 * x + 1] = source[x * 2 + 1]; + dest[4 * x + 2] = source[x * 2 + 0]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadR8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0x00; + dest[4 * x + 1] = 0x00; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadR5G6B5ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgb = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); + dest[4 * x + 1] = + static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); + dest[4 * x + 2] = + static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadR5G6B5ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgb = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); + dest[4 * x + 1] = + static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); + dest[4 * x + 2] = + static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadRGBA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ +#if defined(ANGLE_USE_SSE) + if (gl::supportsSSE2()) + { + __m128i brMask = _mm_set1_epi32(0x00ff00ff); + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, + outputDepthPitch); + + size_t x = 0; + + // Make output writes aligned + for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++) + { + uint32_t rgba = source[x]; + dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + + for (; x + 3 < width; x += 4) + { + __m128i sourceData = + _mm_loadu_si128(reinterpret_cast<const __m128i *>(&source[x])); + // Mask out g and a, which don't change + __m128i gaComponents = _mm_andnot_si128(brMask, sourceData); + // Mask out b and r + __m128i brComponents = _mm_and_si128(sourceData, brMask); + // Swap b and r + __m128i brSwapped = _mm_shufflehi_epi16( + _mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), + _MM_SHUFFLE(2, 3, 0, 1)); + __m128i result = _mm_or_si128(gaComponents, brSwapped); + _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), result); + } + + // Perform leftover writes + for (; x < width; x++) + { + uint32_t rgba = source[x]; + dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + } + } + + return; + } +#endif + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba = source[x]; + dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + } + } +} + +void LoadRGBA8ToBGRA4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba8 = source[x]; + auto r4 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 4); + auto g4 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 12); + auto b4 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 20); + auto a4 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 28); + dest[x] = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4; + } + } + } +} + +void LoadRGBA4ToARGB4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = ANGLE_ROTR16(source[x], 4); + } + } + } +} + +void LoadRGBA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); + dest[4 * x + 1] = + static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); + dest[4 * x + 2] = + static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); + dest[4 * x + 3] = + static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); + } + } + } +} + +void LoadRGBA4ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); + dest[4 * x + 1] = + static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); + dest[4 * x + 2] = + static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); + dest[4 * x + 3] = + static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); + } + } + } +} + +void LoadBGRA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t bgra = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12)); + dest[4 * x + 1] = + static_cast<uint8_t>(((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8)); + dest[4 * x + 2] = + static_cast<uint8_t>(((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4)); + dest[4 * x + 3] = + static_cast<uint8_t>(((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0)); + } + } + } +} + +void LoadRGBA8ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba8 = source[x]; + auto r5 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 3); + auto g5 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 11); + auto b5 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 19); + auto a1 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 31); + dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5; + } + } + } +} + +void LoadRGB10A2ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const R10G10B10A2 *source = + priv::OffsetDataPointer<R10G10B10A2>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + R10G10B10A2 rgb10a2 = source[x]; + + uint16_t r5 = static_cast<uint16_t>(rgb10a2.R >> 5u); + uint16_t g5 = static_cast<uint16_t>(rgb10a2.G >> 5u); + uint16_t b5 = static_cast<uint16_t>(rgb10a2.B >> 5u); + uint16_t a1 = static_cast<uint16_t>(rgb10a2.A >> 1u); + + dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5; + } + } + } +} + +void LoadRGB5A1ToA1RGB5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = ANGLE_ROTR16(source[x], 1); + } + } + } +} + +void LoadRGB5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); + dest[4 * x + 1] = + static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); + dest[4 * x + 2] = + static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); + dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0); + } + } + } +} + +void LoadRGB5A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); + dest[4 * x + 1] = + static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); + dest[4 * x + 2] = + static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); + dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0); + } + } + } +} + +void LoadBGR5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t bgra = source[x]; + dest[4 * x + 0] = + static_cast<uint8_t>(((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13)); + dest[4 * x + 1] = + static_cast<uint8_t>(((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8)); + dest[4 * x + 2] = + static_cast<uint8_t>(((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3)); + dest[4 * x + 3] = static_cast<uint8_t>((bgra & 0x0001) ? 0xFF : 0); + } + } + } +} + +void LoadRGB10A2ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba = source[x]; + dest[4 * x + 0] = static_cast<uint8_t>((rgba & 0x000003FF) >> 2); + dest[4 * x + 1] = static_cast<uint8_t>((rgba & 0x000FFC00) >> 12); + dest[4 * x + 2] = static_cast<uint8_t>((rgba & 0x3FF00000) >> 22); + dest[4 * x + 3] = static_cast<uint8_t>(((rgba & 0xC0000000) >> 30) * 0x55); + } + } + } +} + +void LoadRGB16FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]), + gl::float16ToFloat32(source[x * 3 + 1]), + gl::float16ToFloat32(source[x * 3 + 2])); + } + } + } +} + +void LoadRGB32FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], + source[x * 3 + 2]); + } + } + } +} + +void LoadRGB16FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) << 0) | + (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) | + (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22); + } + } + } +} + +void LoadRGB32FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) << 0) | + (gl::float32ToFloat11(source[x * 3 + 1]) << 11) | + (gl::float32ToFloat10(source[x * 3 + 2]) << 22); + } + } + } +} + +void LoadG8R24ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t d = source[x] >> 8; + uint8_t s = source[x] & 0xFF; + dest[x] = d | (s << 24); + } + } + } +} + +void LoadD32FToD32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = gl::clamp01(source[x]); + } + } + } +} + +void LoadD32FS8X24ToD32FS8X24(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *sourceDepth = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + const uint32_t *sourceStencil = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch) + 1; + float *destDepth = + priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); + uint32_t *destStencil = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch) + + 1; + for (size_t x = 0; x < width; x++) + { + destDepth[x * 2] = gl::clamp01(sourceDepth[x * 2]); + destStencil[x * 2] = sourceStencil[x * 2] & 0xFF000000; + } + } + } +} + +void LoadRGB32FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]); + dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]); + dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]); + dest[x * 4 + 3] = gl::Float16One; + } + } + } +} + +void LoadR32ToR16(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = source[x] >> 16; + } + } + } +} + +void LoadR32ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); + + for (size_t x = 0; x < width; x++) + { + dest[x] = source[x] >> 8; + } + } + } +} + +} // namespace angle diff --git a/chromium/third_party/angle/src/image_util/loadimage.h b/chromium/third_party/angle/src/image_util/loadimage.h new file mode 100644 index 00000000000..598e852f185 --- /dev/null +++ b/chromium/third_party/angle/src/image_util/loadimage.h @@ -0,0 +1,618 @@ +// +// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// loadimage.h: Defines image loading functions + +#ifndef IMAGEUTIL_LOADIMAGE_H_ +#define IMAGEUTIL_LOADIMAGE_H_ + +#include <stddef.h> +#include <stdint.h> + +namespace angle +{ + +void LoadA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB8ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB565ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRG8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR5G6B5ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR5G6B5ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA8ToBGRA4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA4ToARGB4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA4ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadBGRA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA8ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB10A2ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB5A1ToA1RGB5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB5A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadBGR5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB10A2ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB16FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB32FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB16FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB32FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadG8R24ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadD32FToD32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadD32FS8X24ToD32FS8X24(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template <typename type, size_t componentCount> +inline void LoadToNative(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template <typename type, uint32_t fourthComponentBits> +inline void LoadToNative3To4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template <size_t componentCount> +inline void Load32FTo16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB32FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template <size_t blockWidth, size_t blockHeight, size_t blockSize> +inline void LoadCompressedToNative(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR32ToR16(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template <typename type, + uint32_t firstBits, + uint32_t secondBits, + uint32_t thirdBits, + uint32_t fourthBits> +inline void Initialize4ComponentData(size_t width, + size_t height, + size_t depth, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR32ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC1RGB8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC1RGB8ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACR11ToR8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACR11SToR8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACRG11ToRG8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACRG11SToRG8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGB8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGB8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGB8A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGB8A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGBA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGBA8ToSRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +} // namespace angle + +#include "loadimage.inl" + +#endif // IMAGEUTIL_LOADIMAGE_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.inl b/chromium/third_party/angle/src/image_util/loadimage.inl index 920e667db15..b8d590ca1b2 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.inl +++ b/chromium/third_party/angle/src/image_util/loadimage.inl @@ -6,7 +6,12 @@ #include "common/mathutil.h" -namespace rx +#include <string.h> + +namespace angle +{ + +namespace priv { template <typename T> @@ -21,6 +26,8 @@ inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_ return reinterpret_cast<const T*>(data + (y * rowPitch) + (z * depthPitch)); } +} // namespace priv + template <typename type, size_t componentCount> inline void LoadToNative(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, @@ -39,8 +46,8 @@ inline void LoadToNative(size_t width, size_t height, size_t depth, { for (size_t z = 0; z < depth; z++) { - const type *source = OffsetDataPointer<type>(input, 0, z, inputRowPitch, inputDepthPitch); - type *dest = OffsetDataPointer<type>(output, 0, z, outputRowPitch, outputDepthPitch); + const type *source = priv::OffsetDataPointer<type>(input, 0, z, inputRowPitch, inputDepthPitch); + type *dest = priv::OffsetDataPointer<type>(output, 0, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, layerSize); } @@ -51,8 +58,8 @@ inline void LoadToNative(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - const type *source = OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); - type *dest = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); + const type *source = priv::OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); + type *dest = priv::OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, width * sizeof(type) * componentCount); } } @@ -70,8 +77,8 @@ inline void LoadToNative3To4(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - const type *source = OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); - type *dest = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); + const type *source = priv::OffsetDataPointer<type>(input, y, z, inputRowPitch, inputDepthPitch); + type *dest = priv::OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x++) { dest[x * 4 + 0] = source[x * 3 + 0]; @@ -94,8 +101,8 @@ inline void Load32FTo16F(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); + const float *source = priv::OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < elementWidth; x++) { @@ -117,8 +124,8 @@ inline void LoadCompressedToNative(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < rows; ++y) { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + const uint8_t *source = priv::OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, columns * blockSize); } } @@ -140,7 +147,7 @@ inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - type *destRow = OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); + type *destRow = priv::OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x++) { type* destPixel = destRow + x * 4; @@ -153,4 +160,4 @@ inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, } } -} +} // namespace angle diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage_etc.cpp b/chromium/third_party/angle/src/image_util/loadimage_etc.cpp index 35bc1530899..b0881f72878 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage_etc.cpp +++ b/chromium/third_party/angle/src/image_util/loadimage_etc.cpp @@ -6,12 +6,13 @@ // loadimage_etc.cpp: Decodes ETC and EAC encoded textures. -#include "libANGLE/renderer/d3d/loadimage_etc.h" +#include "image_util/loadimage.h" -#include "libANGLE/renderer/imageformats.h" -#include "libANGLE/renderer/d3d/loadimage.h" +#include "common/mathutil.h" -namespace rx +#include "image_util/imageformats.h" + +namespace angle { namespace { @@ -45,6 +46,8 @@ static const int intensityModifierNonOpaque[][4] = }; // clang-format on +static const int kNumPixelsInBlock = 16; + struct ETC2Block { // Decodes unsigned single or dual channel block to bytes @@ -93,7 +96,7 @@ struct ETC2Block const auto &block = u.idht.mode.idm.colors.diff; int r = (block.R + block.dR); int g = (block.G + block.dG); - int b = (block.B + block.dB); + int b = (block.B + block.dB); if (r < 0 || r > 31) { decodeTBlock(dest, x, y, w, h, destRowPitch, alphaValues, @@ -138,7 +141,7 @@ struct ETC2Block const auto &block = u.idht.mode.idm.colors.diff; int r = (block.R + block.dR); int g = (block.G + block.dG); - int b = (block.B + block.dB); + int b = (block.B + block.dB); if (r < 0 || r > 31) { transcodeTBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha); @@ -165,18 +168,15 @@ struct ETC2Block } private: - union - { + union { // Individual, differential, H and T modes struct { - union - { + union { // Individual and differential modes struct { - union - { + union { struct // Individual colors { unsigned char R2 : 4; @@ -286,8 +286,7 @@ struct ETC2Block // Single channel block struct { - union - { + union { unsigned char us; signed char s; } base_codeword; @@ -361,7 +360,7 @@ struct ETC2Block int b1 = extend_4to8bits(block.B1); int r2 = extend_4to8bits(block.R2); int g2 = extend_4to8bits(block.G2); - int b2 = extend_4to8bits(block.B2); + int b2 = extend_4to8bits(block.B2); decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } @@ -381,7 +380,7 @@ struct ETC2Block int r1 = extend_5to8bits(block.R); int r2 = extend_5to8bits(block.R + block.dR); int g2 = extend_5to8bits(block.G + block.dG); - int b2 = extend_5to8bits(block.B + block.dB); + int b2 = extend_5to8bits(block.B + block.dB); decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } @@ -529,7 +528,7 @@ struct ETC2Block int b2 = extend_4to8bits(block.HB2); static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64}; - const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | + const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0)]; const R8G8B8A8 paintColors[4] = { @@ -599,7 +598,7 @@ struct ETC2Block size_t bitIndex = x * 4 + y; size_t bitOffset = bitIndex & 7; size_t lsb = (u.idht.pixelIndexLSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; - size_t msb = (u.idht.pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; + size_t msb = (u.idht.pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; return (msb << 1) | lsb; } @@ -632,10 +631,13 @@ struct ETC2Block (static_cast<uint16_t>(rgba.B >> 3) << 0); } - uint32_t matchBC1Bits(const R8G8B8A8 *rgba, + uint32_t matchBC1Bits(const int *pixelIndices, + const int *pixelIndexCounts, + const R8G8B8A8 *subblockColors, + size_t numColors, const R8G8B8A8 &minColor, const R8G8B8A8 &maxColor, - bool opaque) const + bool nonOpaquePunchThroughAlpha) const { // Project each pixel on the (maxColor, minColor) line to decide which // BC1 code to assign to it. @@ -656,102 +658,127 @@ struct ETC2Block decodedColors[i][2] * direction[2]; } - uint32_t bits = 0; - if (opaque) + ASSERT(numColors <= kNumPixelsInBlock); + + int encodedColors[kNumPixelsInBlock]; + if (nonOpaquePunchThroughAlpha) { - for (int i = 15; i >= 0; i--) + for (size_t i = 0; i < numColors; i++) { - // In opaque mode, the code is from 0 to 3. - - bits <<= 2; - const int dot = - rgba[i].R * direction[0] + rgba[i].G * direction[1] + rgba[i].B * direction[2]; - const int factor = gl::clamp( - static_cast<int>( - (static_cast<float>(dot - stops[1]) / (stops[0] - stops[1])) * 3 + 0.5f), - 0, 3); - switch (factor) + const int count = pixelIndexCounts[i]; + if (count > 0) { - case 0: - bits |= 1; - break; - case 1: - bits |= 3; - break; - case 2: - bits |= 2; - break; - case 3: - default: - bits |= 0; - break; + // In non-opaque mode, 3 is for tranparent pixels. + + if (0 == subblockColors[i].A) + { + encodedColors[i] = 3; + } + else + { + const R8G8B8A8 &pixel = subblockColors[i]; + const int dot = pixel.R * direction[0] + pixel.G * direction[1] + + pixel.B * direction[2]; + const int factor = gl::clamp( + static_cast<int>( + (static_cast<float>(dot - stops[1]) / (stops[0] - stops[1])) * 2 + + 0.5f), + 0, 2); + switch (factor) + { + case 0: + encodedColors[i] = 0; + break; + case 1: + encodedColors[i] = 2; + break; + case 2: + default: + encodedColors[i] = 1; + break; + } + } } } } else { - for (int i = 15; i >= 0; i--) + for (size_t i = 0; i < numColors; i++) { - // In non-opaque mode, 3 is for tranparent pixels. - - bits <<= 2; - if (0 == rgba[i].A) + const int count = pixelIndexCounts[i]; + if (count > 0) { - bits |= 3; - } - else - { - const int dot = rgba[i].R * direction[0] + rgba[i].G * direction[1] + - rgba[i].B * direction[2]; + // In opaque mode, the code is from 0 to 3. + + const R8G8B8A8 &pixel = subblockColors[i]; + const int dot = + pixel.R * direction[0] + pixel.G * direction[1] + pixel.B * direction[2]; const int factor = gl::clamp( static_cast<int>( - (static_cast<float>(dot - stops[1]) / (stops[0] - stops[1])) * 2 + + (static_cast<float>(dot - stops[1]) / (stops[0] - stops[1])) * 3 + 0.5f), - 0, 2); + 0, 3); switch (factor) { case 0: - bits |= 0; + encodedColors[i] = 1; break; case 1: - bits |= 2; + encodedColors[i] = 3; break; case 2: + encodedColors[i] = 2; + break; + case 3: default: - bits |= 1; + encodedColors[i] = 0; break; } } } } + uint32_t bits = 0; + for (int i = kNumPixelsInBlock - 1; i >= 0; i--) + { + bits <<= 2; + bits |= encodedColors[pixelIndices[i]]; + } + return bits; } void packBC1(void *bc1, - const R8G8B8A8 *rgba, - const R8G8B8A8 &minColor, - const R8G8B8A8 &maxColor, - bool opaque) const + const int *pixelIndices, + const int *pixelIndexCounts, + const R8G8B8A8 *subblockColors, + size_t numColors, + int minColorIndex, + int maxColorIndex, + bool nonOpaquePunchThroughAlpha) const { + const R8G8B8A8 &minColor = subblockColors[minColorIndex]; + const R8G8B8A8 &maxColor = subblockColors[maxColorIndex]; + uint32_t bits; uint16_t max16 = RGB8ToRGB565(maxColor); uint16_t min16 = RGB8ToRGB565(minColor); if (max16 != min16) { // Find the best BC1 code for each pixel - bits = matchBC1Bits(rgba, minColor, maxColor, opaque); + bits = matchBC1Bits(pixelIndices, pixelIndexCounts, subblockColors, numColors, minColor, + maxColor, nonOpaquePunchThroughAlpha); } else { // Same colors, BC1 index 0 is the color in both opaque and transparent mode bits = 0; // BC1 index 3 is transparent - if (!opaque) + if (nonOpaquePunchThroughAlpha) { - for (int i = 0; i < 16; i++) + for (int i = 0; i < kNumPixelsInBlock; i++) { - if (0 == rgba[i].A) + if (0 == subblockColors[pixelIndices[i]].A) { bits |= (3 << (i * 2)); } @@ -764,15 +791,7 @@ struct ETC2Block std::swap(max16, min16); uint32_t xorMask = 0; - if (opaque) - { - // In opaque mode switching the two colors is doing the - // following code swaps: 0 <-> 1 and 2 <-> 3. This is - // equivalent to flipping the first bit of each code - // (5 = 0b0101) - xorMask = 0x55555555; - } - else + if (nonOpaquePunchThroughAlpha) { // In transparent mode switching the colors is doing the // following code swap: 0 <-> 1. 0xA selects the second bit of @@ -782,6 +801,14 @@ struct ETC2Block // 0 or 1. xorMask = ~((bits >> 1) | 0xAAAAAAAA); } + else + { + // In opaque mode switching the two colors is doing the + // following code swaps: 0 <-> 1 and 2 <-> 3. This is + // equivalent to flipping the first bit of each code + // (5 = 0b0101) + xorMask = 0x55555555; + } bits ^= xorMask; } @@ -794,15 +821,15 @@ struct ETC2Block // Encode the opaqueness in the order of the two BC1 colors BC1Block *dest = reinterpret_cast<BC1Block *>(bc1); - if (opaque) + if (nonOpaquePunchThroughAlpha) { - dest->color0 = max16; - dest->color1 = min16; + dest->color0 = min16; + dest->color1 = max16; } else { - dest->color0 = min16; - dest->color1 = max16; + dest->color0 = max16; + dest->color1 = min16; } dest->bits = bits; } @@ -821,7 +848,7 @@ struct ETC2Block int b1 = extend_4to8bits(block.B1); int r2 = extend_4to8bits(block.R2); int g2 = extend_4to8bits(block.G2); - int b2 = extend_4to8bits(block.B2); + int b2 = extend_4to8bits(block.B2); transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } @@ -840,80 +867,98 @@ struct ETC2Block int r1 = extend_5to8bits(block.R); int r2 = extend_5to8bits(block.R + block.dR); int g2 = extend_5to8bits(block.G + block.dG); - int b2 = extend_5to8bits(block.B + block.dB); + int b2 = extend_5to8bits(block.B + block.dB); transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } - void decodeSubblock(R8G8B8A8 *rgbaBlock, - size_t x, - size_t y, - size_t w, - size_t h, - const uint8_t alphaValues[4][4], - bool flipbit, - size_t subblockIdx, - const R8G8B8A8 subblockColors[2][4]) const + void extractPixelIndices(int *pixelIndices, + int *pixelIndicesCounts, + size_t x, + size_t y, + size_t w, + size_t h, + bool flipbit, + size_t subblockIdx) const { size_t dxBegin = 0; size_t dxEnd = 4; size_t dyBegin = subblockIdx * 2; - size_t dyEnd = dyBegin + 2; + size_t dyEnd = dyBegin + 2; if (!flipbit) { std::swap(dxBegin, dyBegin); std::swap(dxEnd, dyEnd); } - for (size_t j = dyBegin; j < dyEnd && (y + j) < h; j++) + for (size_t j = dyBegin; j < dyEnd; j++) { - R8G8B8A8 *row = &rgbaBlock[j * 4]; - for (size_t i = dxBegin; i < dxEnd && (x + i) < w; i++) + int *row = &pixelIndices[j * 4]; + for (size_t i = dxBegin; i < dxEnd; i++) { - const size_t pixelIndex = getIndex(i, j); - row[i] = subblockColors[subblockIdx][pixelIndex]; - row[i].A = alphaValues[j][i]; + const size_t pixelIndex = subblockIdx * 4 + getIndex(i, j); + row[i] = static_cast<int>(pixelIndex); + pixelIndicesCounts[pixelIndex]++; } } } - void selectEndPointPCA(const R8G8B8A8 *pixels, R8G8B8A8 *minColor, R8G8B8A8 *maxColor) const + void selectEndPointPCA(const int *pixelIndexCounts, + const R8G8B8A8 *subblockColors, + size_t numColors, + int *minColorIndex, + int *maxColorIndex) const { - static const int kNumPixels = 16; - // determine color distribution int mu[3], min[3], max[3]; for (int ch = 0; ch < 3; ch++) { - int muv, minv, maxv; - - muv = minv = maxv = (&pixels[0].R)[ch]; - for (size_t i = 1; i < kNumPixels; i++) + int muv = 0; + int minv = 255; + int maxv = 0; + for (size_t i = 0; i < numColors; i++) { - muv += (&pixels[i].R)[ch]; - minv = std::min<int>(minv, (&pixels[i].R)[ch]); - maxv = std::max<int>(maxv, (&pixels[i].R)[ch]); + const int count = pixelIndexCounts[i]; + if (count > 0) + { + const auto &pixel = subblockColors[i]; + if (pixel.A > 0) + { + // Non-transparent pixels + muv += (&pixel.R)[ch] * count; + minv = std::min<int>(minv, (&pixel.R)[ch]); + maxv = std::max<int>(maxv, (&pixel.R)[ch]); + } + } } - mu[ch] = (muv + kNumPixels / 2) / kNumPixels; + mu[ch] = (muv + kNumPixelsInBlock / 2) / kNumPixelsInBlock; min[ch] = minv; max[ch] = maxv; } // determine covariance matrix int cov[6] = {0, 0, 0, 0, 0, 0}; - for (size_t i = 0; i < kNumPixels; i++) + for (size_t i = 0; i < numColors; i++) { - int r = pixels[i].R - mu[0]; - int g = pixels[i].G - mu[1]; - int b = pixels[i].B - mu[2]; - - cov[0] += r * r; - cov[1] += r * g; - cov[2] += r * b; - cov[3] += g * g; - cov[4] += g * b; - cov[5] += b * b; + const int count = pixelIndexCounts[i]; + if (count > 0) + { + const auto &pixel = subblockColors[i]; + if (pixel.A > 0) + { + int r = pixel.R - mu[0]; + int g = pixel.G - mu[1]; + int b = pixel.B - mu[2]; + + cov[0] += r * r * count; + cov[1] += r * g * count; + cov[2] += r * b * count; + cov[3] += g * g * count; + cov[4] += g * b * count; + cov[5] += b * b * count; + } + } } // Power iteration algorithm to get the eigenvalues and eigenvector @@ -948,7 +993,7 @@ struct ETC2Block int vr, vg, vb; static const float kDefaultLuminanceThreshold = 4.0f * 255; - static const float kQuantizeRange = 512.0f; + static const float kQuantizeRange = 512.0f; if (eigenvalue < kDefaultLuminanceThreshold) // too small, default to luminance { // Luminance weights defined by ITU-R Recommendation BT.601, scaled by 1000 @@ -969,27 +1014,35 @@ struct ETC2Block } // Pick colors at extreme points - int minD = pixels[0].R * vr + pixels[0].G * vg + pixels[0].B * vb; - int maxD = minD; + int minD = INT_MAX; + int maxD = 0; size_t minIndex = 0; size_t maxIndex = 0; - for (size_t i = 1; i < kNumPixels; i++) + for (size_t i = 0; i < numColors; i++) { - int dot = pixels[i].R * vr + pixels[i].G * vg + pixels[i].B * vb; - if (dot < minD) - { - minD = dot; - minIndex = i; - } - if (dot > maxD) + const int count = pixelIndexCounts[i]; + if (count > 0) { - maxD = dot; - maxIndex = i; + const auto &pixel = subblockColors[i]; + if (pixel.A > 0) + { + int dot = pixel.R * vr + pixel.G * vg + pixel.B * vb; + if (dot < minD) + { + minD = dot; + minIndex = i; + } + if (dot > maxD) + { + maxD = dot; + maxIndex = i; + } + } } } - *minColor = pixels[minIndex]; - *maxColor = pixels[maxIndex]; + *minColorIndex = static_cast<int>(minIndex); + *maxColorIndex = static_cast<int>(maxIndex); } void transcodeIndividualOrDifferentialBlockToBC1(uint8_t *dest, @@ -1012,45 +1065,60 @@ struct ETC2Block // select axis by principal component analysis (PCA) to use as // our two BC1 endpoints and then map pixels to BC1 by projecting on the // line between the two endpoints and choosing the right fraction. - // - // In the future, we have a potential improvements to this algorithm. - // 1. We don't actually need to decode ETC blocks to RGBs. Instead, - // the subblock colors and pixel indices alreay contains enough - // information for transcode. A direct mapping would be more - // efficient here. + + // The goal of this algorithm is make it faster than decode ETC to RGBs + // and then encode to BC. To achieve this, we only extract subblock + // colors, pixel indices, and counts of each pixel indices from ETC. + // With those information, we can only encode used subblock colors + // to BC1, and copy the bits to the right pixels. + // Fully decode and encode need to process 16 RGBA pixels. With this + // algorithm, it's 8 pixels at maximum for a individual or + // differential block. Saves us bandwidth and computations. + + static const size_t kNumColors = 8; const auto intensityModifier = nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault; // Compute the colors that pixels can have in each subblock both for // the decoding of the RGBA data and BC1 encoding - R8G8B8A8 subblockColors[2][4]; + R8G8B8A8 subblockColors[kNumColors]; for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++) { - const int i1 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx]; - subblockColors[0][modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1); + if (nonOpaquePunchThroughAlpha && (modifierIdx == 2)) + { + // In ETC opaque punch through formats, individual and + // differential blocks take index 2 as transparent pixel. + // Thus we don't need to compute its color, just assign it + // as black. + subblockColors[modifierIdx] = createRGBA(0, 0, 0, 0); + subblockColors[4 + modifierIdx] = createRGBA(0, 0, 0, 0); + } + else + { + const int i1 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx]; + subblockColors[modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1); - const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx]; - subblockColors[1][modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2); + const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx]; + subblockColors[4 + modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2); + } } - R8G8B8A8 rgbaBlock[16]; - // Decode the block in rgbaBlock. + int pixelIndices[kNumPixelsInBlock]; + int pixelIndexCounts[kNumColors] = {0}; + // Extract pixel indices from a ETC block. for (size_t blockIdx = 0; blockIdx < 2; blockIdx++) { - decodeSubblock(rgbaBlock, x, y, w, h, alphaValues, u.idht.mode.idm.flipbit, blockIdx, - subblockColors); - } - if (nonOpaquePunchThroughAlpha) - { - decodePunchThroughAlphaBlock(reinterpret_cast<uint8_t *>(rgbaBlock), x, y, w, h, - sizeof(R8G8B8A8) * 4); + extractPixelIndices(pixelIndices, pixelIndexCounts, x, y, w, h, u.idht.mode.idm.flipbit, + blockIdx); } - R8G8B8A8 minColor, maxColor; - selectEndPointPCA(rgbaBlock, &minColor, &maxColor); + int minColorIndex, maxColorIndex; + selectEndPointPCA(pixelIndexCounts, subblockColors, kNumColors, &minColorIndex, + &maxColorIndex); - packBC1(dest, rgbaBlock, minColor, maxColor, !nonOpaquePunchThroughAlpha); + packBC1(dest, pixelIndices, pixelIndexCounts, subblockColors, kNumColors, minColorIndex, + maxColorIndex, nonOpaquePunchThroughAlpha); } void transcodeTBlockToBC1(uint8_t *dest, @@ -1177,9 +1245,9 @@ void LoadR11EACToR8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1209,9 +1277,9 @@ void LoadRG11EACToRG8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1245,9 +1313,9 @@ void LoadETC2RGB8ToRGBA8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1277,9 +1345,9 @@ void LoadETC2RGB8ToBC1(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); - uint8_t *destRow = - OffsetDataPointer<uint8_t>(output, y / 4, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); + uint8_t *destRow = priv::OffsetDataPointer<uint8_t>(output, y / 4, z, outputRowPitch, + outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1311,9 +1379,9 @@ void LoadETC2RGBA8ToRGBA8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1501,4 +1569,4 @@ void LoadETC2SRGBA8ToSRGBA8(size_t width, outputRowPitch, outputDepthPitch, true); } -} // namespace rx +} // namespace angle diff --git a/chromium/third_party/angle/src/libANGLE/Buffer.cpp b/chromium/third_party/angle/src/libANGLE/Buffer.cpp index 3523b32ac75..7fd524427fc 100644 --- a/chromium/third_party/angle/src/libANGLE/Buffer.cpp +++ b/chromium/third_party/angle/src/libANGLE/Buffer.cpp @@ -44,45 +44,33 @@ const std::string &Buffer::getLabel() const return mLabel; } -Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) +Error Buffer::bufferData(GLenum target, const void *data, GLsizeiptr size, GLenum usage) { - gl::Error error = mBuffer->setData(data, size, usage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mBuffer->setData(target, data, size, usage)); mIndexRangeCache.clear(); mUsage = usage; mSize = size; - return error; + return NoError(); } -Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) +Error Buffer::bufferSubData(GLenum target, const void *data, GLsizeiptr size, GLintptr offset) { - gl::Error error = mBuffer->setSubData(data, size, offset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mBuffer->setSubData(target, data, size, offset)); mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset), static_cast<unsigned int>(size)); - return error; + return NoError(); } Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) { - gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size)); mIndexRangeCache.invalidateRange(static_cast<unsigned int>(destOffset), static_cast<unsigned int>(size)); - return error; + return NoError(); } Error Buffer::map(GLenum access) @@ -178,18 +166,14 @@ Error Buffer::getIndexRange(GLenum type, { if (mIndexRangeCache.findRange(type, offset, count, primitiveRestartEnabled, outRange)) { - return gl::Error(GL_NO_ERROR); + return NoError(); } - Error error = mBuffer->getIndexRange(type, offset, count, primitiveRestartEnabled, outRange); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mBuffer->getIndexRange(type, offset, count, primitiveRestartEnabled, outRange)); mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange); - return Error(GL_NO_ERROR); + return NoError(); } } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/Buffer.h b/chromium/third_party/angle/src/libANGLE/Buffer.h index 6c951ef5865..ad5f2e91933 100644 --- a/chromium/third_party/angle/src/libANGLE/Buffer.h +++ b/chromium/third_party/angle/src/libANGLE/Buffer.h @@ -34,8 +34,8 @@ class Buffer final : public RefCountObject, public LabeledObject void setLabel(const std::string &label) override; const std::string &getLabel() const override; - Error bufferData(const void *data, GLsizeiptr size, GLenum usage); - Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); + Error bufferData(GLenum target, const void *data, GLsizeiptr size, GLenum usage); + Error bufferSubData(GLenum target, const void *data, GLsizeiptr size, GLintptr offset); Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); Error map(GLenum access); Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access); diff --git a/chromium/third_party/angle/src/libANGLE/Caps.cpp b/chromium/third_party/angle/src/libANGLE/Caps.cpp index 63d964b8d08..72a262b9974 100644 --- a/chromium/third_party/angle/src/libANGLE/Caps.cpp +++ b/chromium/third_party/angle/src/libANGLE/Caps.cpp @@ -70,6 +70,11 @@ void TextureCapsMap::remove(GLenum internalFormat) } } +void TextureCapsMap::clear() +{ + mCapsMap.clear(); +} + const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const { static TextureCaps defaultUnsupportedTexture; @@ -160,6 +165,10 @@ Extensions::Extensions() lossyETCDecode(false), bindUniformLocation(false), syncQuery(false), + copyTexture(false), + webglCompatibility(false), + bindGeneratesResource(false), + robustClientMemory(false), colorBufferFloat(false), multisampleCompatibility(false), framebufferMixedSamples(false), @@ -172,77 +181,13 @@ std::vector<std::string> Extensions::getStrings() const { std::vector<std::string> extensionStrings; - // clang-format off - // | Extension name | Supported flag | Output vector | - InsertExtensionString("GL_OES_element_index_uint", elementIndexUint, &extensionStrings); - InsertExtensionString("GL_OES_packed_depth_stencil", packedDepthStencil, &extensionStrings); - InsertExtensionString("GL_OES_get_program_binary", getProgramBinary, &extensionStrings); - InsertExtensionString("GL_OES_rgb8_rgba8", rgb8rgba8, &extensionStrings); - InsertExtensionString("GL_EXT_texture_format_BGRA8888", textureFormatBGRA8888, &extensionStrings); - InsertExtensionString("GL_EXT_read_format_bgra", readFormatBGRA, &extensionStrings); - InsertExtensionString("GL_NV_pixel_buffer_object", pixelBufferObject, &extensionStrings); - InsertExtensionString("GL_OES_mapbuffer", mapBuffer, &extensionStrings); - InsertExtensionString("GL_EXT_map_buffer_range", mapBufferRange, &extensionStrings); - InsertExtensionString("GL_EXT_color_buffer_half_float", colorBufferHalfFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_half_float", textureHalfFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_half_float_linear", textureHalfFloatLinear, &extensionStrings); - InsertExtensionString("GL_OES_texture_float", textureFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_float_linear", textureFloatLinear, &extensionStrings); - InsertExtensionString("GL_EXT_texture_rg", textureRG, &extensionStrings); - InsertExtensionString("GL_EXT_texture_compression_dxt1", textureCompressionDXT1, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_compression_dxt3", textureCompressionDXT3, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_compression_dxt5", textureCompressionDXT5, &extensionStrings); - InsertExtensionString("GL_KHR_texture_compression_astc_hdr", textureCompressionASTCHDR, &extensionStrings); - InsertExtensionString("GL_KHR_texture_compression_astc_ldr", textureCompressionASTCLDR, &extensionStrings); - InsertExtensionString("GL_OES_compressed_ETC1_RGB8_texture", compressedETC1RGB8Texture, &extensionStrings); - InsertExtensionString("GL_EXT_sRGB", sRGB, &extensionStrings); - InsertExtensionString("GL_ANGLE_depth_texture", depthTextures, &extensionStrings); - InsertExtensionString("GL_OES_depth32", depth32, &extensionStrings); - InsertExtensionString("GL_EXT_texture_storage", textureStorage, &extensionStrings); - InsertExtensionString("GL_OES_texture_npot", textureNPOT, &extensionStrings); - InsertExtensionString("GL_EXT_draw_buffers", drawBuffers, &extensionStrings); - InsertExtensionString("GL_EXT_texture_filter_anisotropic", textureFilterAnisotropic, &extensionStrings); - InsertExtensionString("GL_EXT_occlusion_query_boolean", occlusionQueryBoolean, &extensionStrings); - InsertExtensionString("GL_NV_fence", fence, &extensionStrings); - InsertExtensionString("GL_ANGLE_timer_query", timerQuery, &extensionStrings); - InsertExtensionString("GL_EXT_disjoint_timer_query", disjointTimerQuery, &extensionStrings); - InsertExtensionString("GL_EXT_robustness", robustness, &extensionStrings); - InsertExtensionString("GL_EXT_blend_minmax", blendMinMax, &extensionStrings); - InsertExtensionString("GL_ANGLE_framebuffer_blit", framebufferBlit, &extensionStrings); - InsertExtensionString("GL_ANGLE_framebuffer_multisample", framebufferMultisample, &extensionStrings); - InsertExtensionString("GL_ANGLE_instanced_arrays", instancedArrays, &extensionStrings); - InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings); - InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings); - InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings); - InsertExtensionString("GL_NV_shader_framebuffer_fetch", NVshaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_ARM_shader_framebuffer_fetch", ARMshaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_EXT_shader_framebuffer_fetch", shaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings); - InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings); - InsertExtensionString("GL_OES_fbo_render_mipmap", fboRenderMipmap, &extensionStrings); - InsertExtensionString("GL_EXT_discard_framebuffer", discardFramebuffer, &extensionStrings); - InsertExtensionString("GL_EXT_debug_marker", debugMarker, &extensionStrings); - InsertExtensionString("GL_OES_EGL_image", eglImage, &extensionStrings); - InsertExtensionString("GL_OES_EGL_image_external", eglImageExternal, &extensionStrings); - InsertExtensionString("GL_OES_EGL_image_external_essl3", eglImageExternalEssl3, &extensionStrings); - InsertExtensionString("GL_NV_EGL_stream_consumer_external", eglStreamConsumerExternal, &extensionStrings); - InsertExtensionString("GL_EXT_unpack_subimage", unpackSubimage, &extensionStrings); - InsertExtensionString("GL_NV_pack_subimage", packSubimage, &extensionStrings); - InsertExtensionString("GL_EXT_color_buffer_float", colorBufferFloat, &extensionStrings); - InsertExtensionString("GL_OES_vertex_array_object", vertexArrayObject, &extensionStrings); - InsertExtensionString("GL_KHR_debug", debug, &extensionStrings); - // TODO(jmadill): Enable this when complete. - //InsertExtensionString("GL_KHR_no_error", noError, &extensionStrings); - - InsertExtensionString("GL_ANGLE_lossy_etc_decode", lossyETCDecode, &extensionStrings); - InsertExtensionString("GL_CHROMIUM_bind_uniform_location", bindUniformLocation, &extensionStrings); - InsertExtensionString("GL_CHROMIUM_sync_query", syncQuery, &extensionStrings); - InsertExtensionString("GL_EXT_multisample_compatibility", multisampleCompatibility, &extensionStrings); - InsertExtensionString("GL_CHROMIUM_framebuffer_mixed_samples", framebufferMixedSamples, &extensionStrings); - InsertExtensionString("GL_EXT_texture_norm16", textureNorm16, &extensionStrings); - InsertExtensionString("GL_CHROMIUM_path_rendering", pathRendering, &extensionStrings); - // clang-format on + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + if (this->*(extensionInfo.second.ExtensionsMember)) + { + extensionStrings.push_back(extensionInfo.first); + } + } return extensionStrings; } @@ -553,6 +498,104 @@ void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps) textureNorm16 = DetermineTextureNorm16Support(textureCaps); } +const ExtensionInfoMap &GetExtensionInfoMap() +{ + auto buildExtensionInfoMap = []() { + auto enableableExtension = [](ExtensionInfo::ExtensionBool member) { + ExtensionInfo info; + info.Enableable = true; + info.ExtensionsMember = member; + return info; + }; + + auto esOnlyExtension = [](ExtensionInfo::ExtensionBool member) { + ExtensionInfo info; + info.ExtensionsMember = member; + return info; + }; + + // clang-format off + ExtensionInfoMap map; + map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUint); + map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencil); + map["GL_OES_get_program_binary"] = esOnlyExtension(&Extensions::getProgramBinary); + map["GL_OES_rgb8_rgba8"] = esOnlyExtension(&Extensions::rgb8rgba8); + map["GL_EXT_texture_format_BGRA8888"] = esOnlyExtension(&Extensions::textureFormatBGRA8888); + map["GL_EXT_read_format_bgra"] = esOnlyExtension(&Extensions::readFormatBGRA); + map["GL_NV_pixel_buffer_object"] = esOnlyExtension(&Extensions::pixelBufferObject); + map["GL_OES_mapbuffer"] = esOnlyExtension(&Extensions::mapBuffer); + map["GL_EXT_map_buffer_range"] = esOnlyExtension(&Extensions::mapBufferRange); + map["GL_EXT_color_buffer_half_float"] = esOnlyExtension(&Extensions::colorBufferHalfFloat); + map["GL_OES_texture_half_float"] = esOnlyExtension(&Extensions::textureHalfFloat); + map["GL_OES_texture_half_float_linear"] = esOnlyExtension(&Extensions::textureHalfFloatLinear); + map["GL_OES_texture_float"] = esOnlyExtension(&Extensions::textureFloat); + map["GL_OES_texture_float_linear"] = esOnlyExtension(&Extensions::textureFloatLinear); + map["GL_EXT_texture_rg"] = esOnlyExtension(&Extensions::textureRG); + map["GL_EXT_texture_compression_dxt1"] = esOnlyExtension(&Extensions::textureCompressionDXT1); + map["GL_ANGLE_texture_compression_dxt3"] = esOnlyExtension(&Extensions::textureCompressionDXT3); + map["GL_ANGLE_texture_compression_dxt5"] = esOnlyExtension(&Extensions::textureCompressionDXT5); + map["GL_KHR_texture_compression_astc_hdr"] = esOnlyExtension(&Extensions::textureCompressionASTCHDR); + map["GL_KHR_texture_compression_astc_ldr"] = esOnlyExtension(&Extensions::textureCompressionASTCLDR); + map["GL_OES_compressed_ETC1_RGB8_texture"] = esOnlyExtension(&Extensions::compressedETC1RGB8Texture); + map["GL_EXT_sRGB"] = esOnlyExtension(&Extensions::sRGB); + map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextures); + map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32); + map["GL_EXT_texture_storage"] = esOnlyExtension(&Extensions::textureStorage); + map["GL_OES_texture_npot"] = esOnlyExtension(&Extensions::textureNPOT); + map["GL_EXT_draw_buffers"] = esOnlyExtension(&Extensions::drawBuffers); + map["GL_EXT_texture_filter_anisotropic"] = esOnlyExtension(&Extensions::textureFilterAnisotropic); + map["GL_EXT_occlusion_query_boolean"] = esOnlyExtension(&Extensions::occlusionQueryBoolean); + map["GL_NV_fence"] = esOnlyExtension(&Extensions::fence); + map["GL_ANGLE_timer_query"] = esOnlyExtension(&Extensions::timerQuery); + map["GL_EXT_disjoint_timer_query"] = esOnlyExtension(&Extensions::disjointTimerQuery); + map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustness); + map["GL_EXT_blend_minmax"] = esOnlyExtension(&Extensions::blendMinMax); + map["GL_ANGLE_framebuffer_blit"] = esOnlyExtension(&Extensions::framebufferBlit); + map["GL_ANGLE_framebuffer_multisample"] = esOnlyExtension(&Extensions::framebufferMultisample); + map["GL_ANGLE_instanced_arrays"] = esOnlyExtension(&Extensions::instancedArrays); + map["GL_ANGLE_pack_reverse_row_order"] = esOnlyExtension(&Extensions::packReverseRowOrder); + map["GL_OES_standard_derivatives"] = esOnlyExtension(&Extensions::standardDerivatives); + map["GL_EXT_shader_texture_lod"] = esOnlyExtension(&Extensions::shaderTextureLOD); + map["GL_NV_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::NVshaderFramebufferFetch); + map["GL_ARM_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::ARMshaderFramebufferFetch); + map["GL_EXT_shader_framebuffer_fetch"] = esOnlyExtension(&Extensions::shaderFramebufferFetch); + map["GL_EXT_frag_depth"] = esOnlyExtension(&Extensions::fragDepth); + map["GL_ANGLE_texture_usage"] = esOnlyExtension(&Extensions::textureUsage); + map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSource); + map["GL_OES_fbo_render_mipmap"] = esOnlyExtension(&Extensions::fboRenderMipmap); + map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebuffer); + map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarker); + map["GL_OES_EGL_image"] = esOnlyExtension(&Extensions::eglImage); + map["GL_OES_EGL_image_external"] = esOnlyExtension(&Extensions::eglImageExternal); + map["GL_OES_EGL_image_external_essl3"] = esOnlyExtension(&Extensions::eglImageExternalEssl3); + map["GL_NV_EGL_stream_consumer_external"] = esOnlyExtension(&Extensions::eglStreamConsumerExternal); + map["GL_EXT_unpack_subimage"] = esOnlyExtension(&Extensions::unpackSubimage); + map["GL_NV_pack_subimage"] = esOnlyExtension(&Extensions::packSubimage); + map["GL_EXT_color_buffer_float"] = esOnlyExtension(&Extensions::colorBufferFloat); + map["GL_OES_vertex_array_object"] = esOnlyExtension(&Extensions::vertexArrayObject); + map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug); + // TODO(jmadill): Enable this when complete. + //map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noError); + map["GL_ANGLE_lossy_etc_decode"] = esOnlyExtension(&Extensions::lossyETCDecode); + map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocation); + map["GL_CHROMIUM_sync_query"] = esOnlyExtension(&Extensions::syncQuery); + map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture); + map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility); + map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource); + map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory); + map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibility); + map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples); + map["GL_EXT_texture_norm16"] = esOnlyExtension(&Extensions::textureNorm16); + map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering); + // clang-format on + + return map; + }; + + static const ExtensionInfoMap extensionInfo = buildExtensionInfoMap(); + return extensionInfo; +} + TypePrecision::TypePrecision() { range[0] = 0; @@ -596,33 +639,72 @@ Caps::Caps() maxLODBias(0), maxCubeMapTextureSize(0), maxRenderbufferSize(0), + minAliasedPointSize(0), + maxAliasedPointSize(0), + minAliasedLineWidth(0), + maxAliasedLineWidth(0), + + // Table 20.40 maxDrawBuffers(0), + maxFramebufferWidth(0), + maxFramebufferHeight(0), + maxFramebufferSamples(0), maxColorAttachments(0), maxViewportWidth(0), maxViewportHeight(0), - minAliasedPointSize(0), - maxAliasedPointSize(0), - minAliasedLineWidth(0), - // Table 6.29 + maxSampleMaskWords(0), + maxColorTextureSamples(0), + maxDepthTextureSamples(0), + maxIntegerSamples(0), + maxServerWaitTimeout(0), + + // Table 20.41 + maxVertexAttribRelativeOffset(0), + maxVertexAttribBindings(0), + maxVertexAttribStride(0), maxElementsIndices(0), maxElementsVertices(0), - maxServerWaitTimeout(0), - // Table 6.31 + + // Table 20.43 maxVertexAttributes(0), maxVertexUniformComponents(0), maxVertexUniformVectors(0), maxVertexUniformBlocks(0), maxVertexOutputComponents(0), maxVertexTextureImageUnits(0), - // Table 6.32 + maxVertexAtomicCounterBuffers(0), + maxVertexAtomicCounters(0), + maxVertexImageUniforms(0), + maxVertexShaderStorageBlocks(0), + + // Table 20.44 maxFragmentUniformComponents(0), maxFragmentUniformVectors(0), maxFragmentUniformBlocks(0), maxFragmentInputComponents(0), maxTextureImageUnits(0), + maxFragmentAtomicCounterBuffers(0), + maxFragmentAtomicCounters(0), + maxFragmentImageUniforms(0), + maxFragmentShaderStorageBlocks(0), + minProgramTextureGatherOffset(0), + maxProgramTextureGatherOffset(0), minProgramTexelOffset(0), maxProgramTexelOffset(0), - // Table 6.33 + + // Table 20.45 + maxComputeWorkGroupInvocations(0), + maxComputeUniformBlocks(0), + maxComputeTextureImageUnits(0), + maxComputeSharedMemorySize(0), + maxComputeUniformComponents(0), + maxComputeAtomicCounterBuffers(0), + maxComputeAtomicCounters(0), + maxComputeImageUniforms(0), + maxCombinedComputeUniformComponents(0), + maxComputeShaderStorageBlocks(0), + + // Table 20.46 maxUniformBufferBindings(0), maxUniformBlockSize(0), uniformBufferOffsetAlignment(0), @@ -632,13 +714,35 @@ Caps::Caps() maxVaryingComponents(0), maxVaryingVectors(0), maxCombinedTextureImageUnits(0), - // Table 6.34 + maxCombinedShaderOutputResources(0), + + // Table 20.47 + maxUniformLocations(0), + maxAtomicCounterBufferBindings(0), + maxAtomicCounterBufferSize(0), + maxCombinedAtomicCounterBuffers(0), + maxCombinedAtomicCounters(0), + maxImageUnits(0), + maxCombinedImageUniforms(0), + maxShaderStorageBufferBindings(0), + maxShaderStorageBlockSize(0), + maxCombinedShaderStorageBlocks(0), + shaderStorageBufferOffsetAlignment(0), + + // Table 20.48 maxTransformFeedbackInterleavedComponents(0), maxTransformFeedbackSeparateAttributes(0), maxTransformFeedbackSeparateComponents(0), - // Table 6.35 + + // Table 20.49 maxSamples(0) + { + for (size_t i = 0; i < 3; ++i) + { + maxComputeWorkGroupCount[i] = 0; + maxComputeWorkGroupSize[i] = 0; + } } } @@ -676,7 +780,9 @@ DisplayExtensions::DisplayExtensions() stream(false), streamConsumerGLTexture(false), streamConsumerGLTextureYUV(false), - streamProducerD3DTextureNV12(false) + streamProducerD3DTextureNV12(false), + createContextWebGLCompatibility(false), + createContextBindGeneratesResource(false) { } @@ -685,33 +791,35 @@ std::vector<std::string> DisplayExtensions::getStrings() const std::vector<std::string> extensionStrings; // clang-format off - // | Extension name | Supported flag | Output vector | - InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings); - InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings); - InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings); - InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); - InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); - InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings); - InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings); - InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings); - InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings); - InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); - InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings); - InsertExtensionString("EGL_KHR_image", image, &extensionStrings); - InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings); - InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings); - InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings); - InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings); - InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings); - InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings); - InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings); - InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture_nv12", streamProducerD3DTextureNV12, &extensionStrings); + // | Extension name | Supported flag | Output vector | + InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings); + InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings); + InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); + InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings); + InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings); + InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings); + InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings); + InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); + InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings); + InsertExtensionString("EGL_KHR_image", image, &extensionStrings); + InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings); + InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings); + InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings); + InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings); + InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings); + InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings); + InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings); + InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture_nv12", streamProducerD3DTextureNV12, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings); + InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings); // TODO(jmadill): Enable this when complete. - //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); + //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); // clang-format on return extensionStrings; @@ -759,6 +867,7 @@ std::vector<std::string> ClientExtensions::getStrings() const InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings); InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings); InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings); InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings); InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings); InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings); diff --git a/chromium/third_party/angle/src/libANGLE/Caps.h b/chromium/third_party/angle/src/libANGLE/Caps.h index 0cbc290e210..5a10a3978c0 100644 --- a/chromium/third_party/angle/src/libANGLE/Caps.h +++ b/chromium/third_party/angle/src/libANGLE/Caps.h @@ -14,6 +14,7 @@ #include <set> #include <string> #include <vector> +#include <array> namespace gl { @@ -51,6 +52,7 @@ class TextureCapsMap void insert(GLenum internalFormat, const TextureCaps &caps); void remove(GLenum internalFormat); + void clear(); const TextureCaps &get(GLenum internalFormat) const; @@ -288,6 +290,18 @@ struct Extensions // GL_CHROMIUM_sync_query bool syncQuery; + // GL_CHROMIUM_copy_texture + bool copyTexture; + + // GL_ANGLE_webgl_compatibility + bool webglCompatibility; + + // GL_CHROMIUM_bind_generates_resource + bool bindGeneratesResource; + + // GL_ANGLE_robust_client_memory + bool robustClientMemory; + // ES3 Extension support // GL_EXT_color_buffer_float @@ -308,6 +322,19 @@ struct Extensions bool pathRendering; }; +struct ExtensionInfo +{ + // If this extension can be enabled with glEnableExtension (GL_ANGLE_webgl_compatibility) + bool Enableable = false; + + // Pointer to a boolean member of the Extensions struct + typedef bool(Extensions::*ExtensionBool); + ExtensionBool ExtensionsMember = nullptr; +}; + +using ExtensionInfoMap = std::map<std::string, ExtensionInfo>; +const ExtensionInfoMap &GetExtensionInfoMap(); + struct Limitations { Limitations(); @@ -350,7 +377,7 @@ struct Caps { Caps(); - // Table 6.28, implementation dependent values + // ES 3.1 (April 29, 2015) 20.39: implementation dependent values GLuint64 maxElementIndex; GLuint max3DTextureSize; GLuint max2DTextureSize; @@ -358,16 +385,29 @@ struct Caps GLfloat maxLODBias; GLuint maxCubeMapTextureSize; GLuint maxRenderbufferSize; - GLuint maxDrawBuffers; - GLuint maxColorAttachments; - GLuint maxViewportWidth; - GLuint maxViewportHeight; GLfloat minAliasedPointSize; GLfloat maxAliasedPointSize; GLfloat minAliasedLineWidth; GLfloat maxAliasedLineWidth; - // Table 6.29, implementation dependent values (cont.) + // ES 3.1 (April 29, 2015) 20.40: implementation dependent values (cont.) + GLuint maxDrawBuffers; + GLuint maxFramebufferWidth; + GLuint maxFramebufferHeight; + GLuint maxFramebufferSamples; + GLuint maxColorAttachments; + GLuint maxViewportWidth; + GLuint maxViewportHeight; + GLuint maxSampleMaskWords; + GLuint maxColorTextureSamples; + GLuint maxDepthTextureSamples; + GLuint maxIntegerSamples; + GLuint64 maxServerWaitTimeout; + + // ES 3.1 (April 29, 2015) Table 20.41: Implementation dependent values (cont.) + GLint maxVertexAttribRelativeOffset; + GLint maxVertexAttribBindings; + GLint maxVertexAttribStride; GLuint maxElementsIndices; GLuint maxElementsVertices; std::vector<GLenum> compressedTextureFormats; @@ -385,26 +425,49 @@ struct Caps TypePrecision fragmentHighpInt; TypePrecision fragmentMediumpInt; TypePrecision fragmentLowpInt; - GLuint64 maxServerWaitTimeout; - // Table 6.31, implementation dependent vertex shader limits + // ES 3.1 (April 29, 2015) Table 20.43: Implementation dependent Vertex shader limits GLuint maxVertexAttributes; GLuint maxVertexUniformComponents; GLuint maxVertexUniformVectors; GLuint maxVertexUniformBlocks; GLuint maxVertexOutputComponents; GLuint maxVertexTextureImageUnits; + GLuint maxVertexAtomicCounterBuffers; + GLuint maxVertexAtomicCounters; + GLuint maxVertexImageUniforms; + GLuint maxVertexShaderStorageBlocks; - // Table 6.32, implementation dependent fragment shader limits + // ES 3.1 (April 29, 2015) Table 20.44: Implementation dependent Fragment shader limits GLuint maxFragmentUniformComponents; GLuint maxFragmentUniformVectors; GLuint maxFragmentUniformBlocks; GLuint maxFragmentInputComponents; GLuint maxTextureImageUnits; + GLuint maxFragmentAtomicCounterBuffers; + GLuint maxFragmentAtomicCounters; + GLuint maxFragmentImageUniforms; + GLuint maxFragmentShaderStorageBlocks; + GLint minProgramTextureGatherOffset; + GLuint maxProgramTextureGatherOffset; GLint minProgramTexelOffset; GLint maxProgramTexelOffset; - // Table 6.33, implementation dependent aggregate shader limits + // ES 3.1 (April 29, 2015) Table 20.45: implementation dependent compute shader limits + std::array<GLuint, 3> maxComputeWorkGroupCount; + std::array<GLuint, 3> maxComputeWorkGroupSize; + GLuint maxComputeWorkGroupInvocations; + GLuint maxComputeUniformBlocks; + GLuint maxComputeTextureImageUnits; + GLuint maxComputeSharedMemorySize; + GLuint maxComputeUniformComponents; + GLuint maxComputeAtomicCounterBuffers; + GLuint maxComputeAtomicCounters; + GLuint maxComputeImageUniforms; + GLuint maxCombinedComputeUniformComponents; + GLuint maxComputeShaderStorageBlocks; + + // ES 3.1 (April 29, 2015) Table 20.46: implementation dependent aggregate shader limits GLuint maxUniformBufferBindings; GLuint64 maxUniformBlockSize; GLuint uniformBufferOffsetAlignment; @@ -414,13 +477,27 @@ struct Caps GLuint maxVaryingComponents; GLuint maxVaryingVectors; GLuint maxCombinedTextureImageUnits; - - // Table 6.34, implementation dependent transform feedback limits + GLuint maxCombinedShaderOutputResources; + + // ES 3.1 (April 29, 2015) Table 20.47: implementation dependent aggregate shader limits (cont.) + GLuint maxUniformLocations; + GLuint maxAtomicCounterBufferBindings; + GLuint maxAtomicCounterBufferSize; + GLuint maxCombinedAtomicCounterBuffers; + GLuint maxCombinedAtomicCounters; + GLuint maxImageUnits; + GLuint maxCombinedImageUniforms; + GLuint maxShaderStorageBufferBindings; + GLuint64 maxShaderStorageBlockSize; + GLuint maxCombinedShaderStorageBlocks; + GLuint shaderStorageBufferOffsetAlignment; + + // ES 3.1 (April 29, 2015) Table 20.48: implementation dependent transform feedback limits GLuint maxTransformFeedbackInterleavedComponents; GLuint maxTransformFeedbackSeparateAttributes; GLuint maxTransformFeedbackSeparateComponents; - // Table 6.35, Framebuffer Dependent Values + // ES 3.1 (April 29, 2015) Table 20.49: Framebuffer Dependent Values GLuint maxSamples; }; @@ -518,6 +595,12 @@ struct DisplayExtensions // EGL_ANGLE_stream_producer_d3d_texture_nv12 bool streamProducerD3DTextureNV12; + + // EGL_ANGLE_create_context_webgl_compatibility + bool createContextWebGLCompatibility; + + // EGL_CHROMIUM_create_context_bind_generates_resource + bool createContextBindGeneratesResource; }; struct DeviceExtensions @@ -556,6 +639,9 @@ struct ClientExtensions // EGL_ANGLE_platform_angle_opengl bool platformANGLEOpenGL; + // EGL_ANGLE_platform_angle_null + bool platformANGLENULL; + // EGL_ANGLE_device_creation bool deviceCreation; diff --git a/chromium/third_party/angle/src/libANGLE/Compiler.cpp b/chromium/third_party/angle/src/libANGLE/Compiler.cpp index 33ce14b60b4..b745888f275 100644 --- a/chromium/third_party/angle/src/libANGLE/Compiler.cpp +++ b/chromium/third_party/angle/src/libANGLE/Compiler.cpp @@ -23,17 +23,34 @@ namespace // ShFinalize. size_t activeCompilerHandles = 0; +ShShaderSpec SelectShaderSpec(GLint majorVersion, GLint minorVersion) +{ + if (majorVersion >= 3) + { + if (minorVersion == 1) + { + return SH_GLES3_1_SPEC; + } + else + { + return SH_GLES3_SPEC; + } + } + return SH_GLES2_SPEC; +} + } // anonymous namespace Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) : mImplementation(implFactory->createCompiler()), - mSpec(state.getClientVersion() > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC), + mSpec(SelectShaderSpec(state.getClientMajorVersion(), state.getClientMinorVersion())), mOutputType(mImplementation->getTranslatorOutputType()), mResources(), mFragmentCompiler(nullptr), - mVertexCompiler(nullptr) + mVertexCompiler(nullptr), + mComputeCompiler(nullptr) { - ASSERT(state.getClientVersion() == 2 || state.getClientVersion() == 3); + ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3); const gl::Caps &caps = state.getCaps(); const gl::Extensions &extensions = state.getExtensions(); @@ -62,6 +79,35 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; mResources.MinProgramTexelOffset = caps.minProgramTexelOffset; mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; + + // GLSL ES 3.1 compute shader constants + mResources.MaxImageUnits = caps.maxImageUnits; + mResources.MaxVertexImageUniforms = caps.maxVertexImageUniforms; + mResources.MaxFragmentImageUniforms = caps.maxFragmentImageUniforms; + mResources.MaxComputeImageUniforms = caps.maxComputeImageUniforms; + mResources.MaxCombinedImageUniforms = caps.maxCombinedImageUniforms; + mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources; + + for (size_t index = 0u; index < 3u; ++index) + { + mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index]; + mResources.MaxComputeWorkGroupSize[index] = caps.maxComputeWorkGroupSize[index]; + } + + mResources.MaxComputeUniformComponents = caps.maxComputeUniformComponents; + mResources.MaxComputeTextureImageUnits = caps.maxComputeTextureImageUnits; + + mResources.MaxComputeAtomicCounters = caps.maxComputeAtomicCounters; + mResources.MaxComputeAtomicCounterBuffers = caps.maxComputeAtomicCounterBuffers; + + mResources.MaxVertexAtomicCounters = caps.maxVertexAtomicCounters; + mResources.MaxFragmentAtomicCounters = caps.maxFragmentAtomicCounters; + mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters; + mResources.MaxAtomicCounterBindings = caps.maxAtomicCounterBufferBindings; + mResources.MaxVertexAtomicCounterBuffers = caps.maxVertexAtomicCounterBuffers; + mResources.MaxFragmentAtomicCounterBuffers = caps.maxFragmentAtomicCounterBuffers; + mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers; + mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize; } Compiler::~Compiler() @@ -90,6 +136,15 @@ Error Compiler::release() activeCompilerHandles--; } + if (mComputeCompiler) + { + ShDestruct(mComputeCompiler); + mComputeCompiler = nullptr; + + ASSERT(activeCompilerHandles > 0); + activeCompilerHandles--; + } + if (activeCompilerHandles == 0) { ShFinalize(); @@ -112,7 +167,9 @@ ShHandle Compiler::getCompilerHandle(GLenum type) case GL_FRAGMENT_SHADER: compiler = &mFragmentCompiler; break; - + case GL_COMPUTE_SHADER: + compiler = &mComputeCompiler; + break; default: UNREACHABLE(); return nullptr; diff --git a/chromium/third_party/angle/src/libANGLE/Compiler.h b/chromium/third_party/angle/src/libANGLE/Compiler.h index 03b1a49db52..14226630e45 100644 --- a/chromium/third_party/angle/src/libANGLE/Compiler.h +++ b/chromium/third_party/angle/src/libANGLE/Compiler.h @@ -42,6 +42,7 @@ class Compiler final : angle::NonCopyable ShHandle mFragmentCompiler; ShHandle mVertexCompiler; + ShHandle mComputeCompiler; }; } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/Context.cpp b/chromium/third_party/angle/src/libANGLE/Context.cpp index 25596579e98..a08899011c2 100644 --- a/chromium/third_party/angle/src/libANGLE/Context.cpp +++ b/chromium/third_party/angle/src/libANGLE/Context.cpp @@ -12,6 +12,7 @@ #include <iterator> #include <sstream> #include <string.h> +#include <vector> #include "common/matrix_utils.h" #include "common/platform.h" @@ -34,13 +35,67 @@ #include "libANGLE/VertexArray.h" #include "libANGLE/formatutils.h" #include "libANGLE/validationES.h" +#include "libANGLE/Workarounds.h" #include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/EGLImplFactory.h" +#include "libANGLE/queryconversions.h" namespace { template <typename T> +std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager, + GLsizei numPaths, + const void *paths, + GLuint pathBase) +{ + std::vector<gl::Path *> ret; + ret.reserve(numPaths); + + const auto *nameArray = static_cast<const T *>(paths); + + for (GLsizei i = 0; i < numPaths; ++i) + { + const GLuint pathName = nameArray[i] + pathBase; + + ret.push_back(resourceManager.getPath(pathName)); + } + + return ret; +} + +std::vector<gl::Path *> GatherPaths(gl::ResourceManager &resourceManager, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase) +{ + switch (pathNameType) + { + case GL_UNSIGNED_BYTE: + return GatherPaths<GLubyte>(resourceManager, numPaths, paths, pathBase); + + case GL_BYTE: + return GatherPaths<GLbyte>(resourceManager, numPaths, paths, pathBase); + + case GL_UNSIGNED_SHORT: + return GatherPaths<GLushort>(resourceManager, numPaths, paths, pathBase); + + case GL_SHORT: + return GatherPaths<GLshort>(resourceManager, numPaths, paths, pathBase); + + case GL_UNSIGNED_INT: + return GatherPaths<GLuint>(resourceManager, numPaths, paths, pathBase); + + case GL_INT: + return GatherPaths<GLint>(resourceManager, numPaths, paths, pathBase); + } + + UNREACHABLE(); + return std::vector<gl::Path *>(); +} + +template <typename T> gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params) { gl::Query *queryObject = context->getQuery(id, false, GL_NONE); @@ -84,11 +139,16 @@ void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback) } // Attribute map queries. -EGLint GetClientVersion(const egl::AttributeMap &attribs) +EGLint GetClientMajorVersion(const egl::AttributeMap &attribs) { return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1)); } +EGLint GetClientMinorVersion(const egl::AttributeMap &attribs) +{ + return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0)); +} + GLenum GetResetStrategy(const egl::AttributeMap &attribs) { EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, @@ -120,6 +180,46 @@ bool GetNoError(const egl::AttributeMap &attribs) return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE); } +bool GetWebGLContext(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE); +} + +bool GetBindGeneratesResource(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE); +} + +std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label) +{ + std::string labelName; + if (label != nullptr) + { + size_t labelLength = length < 0 ? strlen(label) : length; + labelName = std::string(label, labelLength); + } + return labelName; +} + +void GetObjectLabelBase(const std::string &objectLabel, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + size_t writeLength = objectLabel.length(); + if (label != nullptr && bufSize > 0) + { + writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length()); + std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); + label[writeLength] = '\0'; + } + + if (length != nullptr) + { + *length = static_cast<GLsizei>(writeLength); + } +} + } // anonymous namespace namespace gl @@ -129,7 +229,9 @@ Context::Context(rx::EGLImplFactory *implFactory, const egl::Config *config, const Context *shareContext, const egl::AttributeMap &attribs) - : ValidationContext(GetClientVersion(attribs), + + : ValidationContext(GetClientMajorVersion(attribs), + GetClientMinorVersion(attribs), &mGLState, mCaps, mTextureCaps, @@ -139,12 +241,14 @@ Context::Context(rx::EGLImplFactory *implFactory, GetNoError(attribs)), mImplementation(implFactory->createContext(mState)), mCompiler(nullptr), - mClientVersion(GetClientVersion(attribs)), + mClientMajorVersion(GetClientMajorVersion(attribs)), + mClientMinorVersion(GetClientMinorVersion(attribs)), mConfig(config), mClientType(EGL_OPENGL_ES_API), mHasBeenCurrent(false), mContextLost(false), mResetStatus(GL_NO_ERROR), + mContextLostForced(false), mResetStrategy(GetResetStrategy(attribs)), mRobustAccess(GetRobustAccess(attribs)), mCurrentSurface(nullptr), @@ -152,9 +256,11 @@ Context::Context(rx::EGLImplFactory *implFactory, { ASSERT(!mRobustAccess); // Unimplemented - initCaps(); + initCaps(GetWebGLContext(attribs)); + initWorkarounds(); - mGLState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs)); + mGLState.initialize(mCaps, mExtensions, mClientMajorVersion, GetDebug(attribs), + GetBindGeneratesResource(attribs)); mFenceNVHandleAllocator.setBaseHandle(0); @@ -182,7 +288,7 @@ Context::Context(rx::EGLImplFactory *implFactory, Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP); mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube); - if (mClientVersion >= 3) + if (mClientMajorVersion >= 3) { // TODO: These could also be enabled via extension Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D); @@ -218,7 +324,7 @@ Context::Context(rx::EGLImplFactory *implFactory, bindPixelPackBuffer(0); bindPixelUnpackBuffer(0); - if (mClientVersion >= 3) + if (mClientMajorVersion >= 3) { // [OpenGL ES 3.0.2] section 2.14.1 pg 85: // In the initial state, a default transform feedback object is bound and treated as @@ -394,19 +500,6 @@ void Context::releaseSurface() mCurrentSurface = nullptr; } -// NOTE: this function should not assume that this context is current! -void Context::markContextLost() -{ - if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) - mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT; - mContextLost = true; -} - -bool Context::isContextLost() -{ - return mContextLost; -} - GLuint Context::createBuffer() { return mResourceManager->createBuffer(); @@ -804,6 +897,49 @@ LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))); } +void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) +{ + LabeledObject *object = getLabeledObject(identifier, name); + ASSERT(object != nullptr); + + std::string labelName = GetObjectLabelFromPointer(length, label); + object->setLabel(labelName); +} + +void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) +{ + LabeledObject *object = getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); + + std::string labelName = GetObjectLabelFromPointer(length, label); + object->setLabel(labelName); +} + +void Context::getObjectLabel(GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label) const +{ + LabeledObject *object = getLabeledObject(identifier, name); + ASSERT(object != nullptr); + + const std::string &objectLabel = object->getLabel(); + GetObjectLabelBase(objectLabel, bufSize, length, label); +} + +void Context::getObjectPtrLabel(const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label) const +{ + LabeledObject *object = getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); + + const std::string &objectLabel = object->getLabel(); + GetObjectLabelBase(objectLabel, bufSize, length, label); +} + bool Context::isSampler(GLuint samplerName) const { return mResourceManager->isSampler(samplerName); @@ -1171,8 +1307,12 @@ void Context::getIntegerv(GLenum pname, GLint *params) case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break; case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break; case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break; - case GL_MAJOR_VERSION: *params = mClientVersion; break; - case GL_MINOR_VERSION: *params = 0; break; + case GL_MAJOR_VERSION: + *params = mClientMajorVersion; + break; + case GL_MINOR_VERSION: + *params = mClientMinorVersion; + break; case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break; case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break; case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break; @@ -1228,7 +1368,129 @@ void Context::getIntegerv(GLenum pname, GLint *params) case GL_GPU_DISJOINT_EXT: *params = mImplementation->getGPUDisjoint(); break; - + case GL_MAX_FRAMEBUFFER_WIDTH: + *params = mCaps.maxFramebufferWidth; + break; + case GL_MAX_FRAMEBUFFER_HEIGHT: + *params = mCaps.maxFramebufferHeight; + break; + case GL_MAX_FRAMEBUFFER_SAMPLES: + *params = mCaps.maxFramebufferSamples; + break; + case GL_MAX_SAMPLE_MASK_WORDS: + *params = mCaps.maxSampleMaskWords; + break; + case GL_MAX_COLOR_TEXTURE_SAMPLES: + *params = mCaps.maxColorTextureSamples; + break; + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + *params = mCaps.maxDepthTextureSamples; + break; + case GL_MAX_INTEGER_SAMPLES: + *params = mCaps.maxIntegerSamples; + break; + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + *params = mCaps.maxVertexAttribRelativeOffset; + break; + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + *params = mCaps.maxVertexAttribBindings; + break; + case GL_MAX_VERTEX_ATTRIB_STRIDE: + *params = mCaps.maxVertexAttribStride; + break; + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxVertexAtomicCounterBuffers; + break; + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + *params = mCaps.maxVertexAtomicCounters; + break; + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + *params = mCaps.maxVertexImageUniforms; + break; + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxVertexShaderStorageBlocks; + break; + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxFragmentAtomicCounterBuffers; + break; + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + *params = mCaps.maxFragmentAtomicCounters; + break; + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + *params = mCaps.maxFragmentImageUniforms; + break; + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxFragmentShaderStorageBlocks; + break; + case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET: + *params = mCaps.minProgramTextureGatherOffset; + break; + case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET: + *params = mCaps.maxProgramTextureGatherOffset; + break; + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + *params = mCaps.maxComputeWorkGroupInvocations; + break; + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + *params = mCaps.maxComputeUniformBlocks; + break; + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + *params = mCaps.maxComputeTextureImageUnits; + break; + case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: + *params = mCaps.maxComputeSharedMemorySize; + break; + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + *params = mCaps.maxComputeUniformComponents; + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxComputeAtomicCounterBuffers; + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + *params = mCaps.maxComputeAtomicCounters; + break; + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + *params = mCaps.maxComputeImageUniforms; + break; + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + *params = mCaps.maxCombinedComputeUniformComponents; + break; + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxComputeShaderStorageBlocks; + break; + case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: + *params = mCaps.maxCombinedShaderOutputResources; + break; + case GL_MAX_UNIFORM_LOCATIONS: + *params = mCaps.maxUniformLocations; + break; + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + *params = mCaps.maxAtomicCounterBufferBindings; + break; + case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: + *params = mCaps.maxAtomicCounterBufferSize; + break; + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxCombinedAtomicCounterBuffers; + break; + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + *params = mCaps.maxCombinedAtomicCounters; + break; + case GL_MAX_IMAGE_UNITS: + *params = mCaps.maxImageUnits; + break; + case GL_MAX_COMBINED_IMAGE_UNIFORMS: + *params = mCaps.maxCombinedImageUniforms; + break; + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + *params = mCaps.maxShaderStorageBufferBindings; + break; + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxCombinedShaderStorageBlocks; + break; + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + *params = mCaps.shaderStorageBufferOffsetAlignment; + break; default: mGLState.getIntegerv(mState, pname, params); break; @@ -1261,6 +1523,10 @@ void Context::getInteger64v(GLenum pname, GLint64 *params) case GL_TIMESTAMP_EXT: *params = mImplementation->getTimestamp(); break; + + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + *params = mCaps.maxShaderStorageBlockSize; + break; default: UNREACHABLE(); break; @@ -1272,22 +1538,79 @@ void Context::getPointerv(GLenum pname, void **params) const mGLState.getPointerv(pname, params); } -bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) +void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data) { // Queries about context capabilities and maximums are answered by Context. // Queries about current GL state values are answered by State. - // Indexed integer queries all refer to current state, so this function is a - // mere passthrough. - return mGLState.getIndexedIntegerv(target, index, data); + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + UNUSED_ASSERTION_VARIABLE(queryStatus); + ASSERT(queryStatus); + + if (nativeType == GL_INT) + { + switch (target) + { + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + ASSERT(index < 3u); + *data = mCaps.maxComputeWorkGroupCount[index]; + break; + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + ASSERT(index < 3u); + *data = mCaps.maxComputeWorkGroupSize[index]; + break; + default: + mGLState.getIntegeri_v(target, index, data); + } + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } } -bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) +void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) { // Queries about context capabilities and maximums are answered by Context. // Queries about current GL state values are answered by State. - // Indexed integer queries all refer to current state, so this function is a - // mere passthrough. - return mGLState.getIndexedInteger64v(target, index, data); + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + UNUSED_ASSERTION_VARIABLE(queryStatus); + ASSERT(queryStatus); + + if (nativeType == GL_INT_64_ANGLEX) + { + mGLState.getInteger64i_v(target, index, data); + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } +} + +void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data) +{ + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + UNUSED_ASSERTION_VARIABLE(queryStatus); + ASSERT(queryStatus); + + if (nativeType == GL_BOOL) + { + mGLState.getBooleani_v(target, index, data); + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } } Error Context::drawArrays(GLenum mode, GLint first, GLsizei count) @@ -1471,11 +1794,147 @@ void Context::stencilThenCoverStrokePath(GLuint path, mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode); } +void Context::coverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = + GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues); +} + +void Context::coverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = + GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType, + transformValues); +} + +void Context::stencilFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = + GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType, + transformValues); +} + +void Context::stencilStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = + GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType, + transformValues); +} + +void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = + GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask, + transformType, transformValues); +} + +void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = + GatherPaths(*mResourceManager, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask, + transformType, transformValues); +} + +void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name) +{ + auto *programObject = getProgram(program); + + programObject->bindFragmentInputLocation(location, name); +} + +void Context::programPathFragmentInputGen(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + auto *programObject = getProgram(program); + + programObject->pathFragmentInputGen(location, genMode, components, coeffs); +} + void Context::handleError(const Error &error) { if (error.isError()) { - mErrors.insert(error.getCode()); + GLenum code = error.getCode(); + mErrors.insert(code); + if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory) + { + markContextLost(); + } if (!error.getMessage().empty()) { @@ -1502,32 +1961,61 @@ GLenum Context::getError() } } +// NOTE: this function should not assume that this context is current! +void Context::markContextLost() +{ + if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) + { + mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT; + mContextLostForced = true; + } + mContextLost = true; +} + +bool Context::isContextLost() +{ + return mContextLost; +} + GLenum Context::getResetStatus() { - //TODO(jmadill): needs MANGLE reworking - if (mResetStatus == GL_NO_ERROR && !mContextLost) + // Even if the application doesn't want to know about resets, we want to know + // as it will allow us to skip all the calls. + if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT) { - // mResetStatus will be set by the markContextLost callback - // in the case a notification is sent - if (mImplementation->testDeviceLost()) + if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR) { - mImplementation->notifyDeviceLost(); + mContextLost = true; } - } - GLenum status = mResetStatus; + // EXT_robustness, section 2.6: If the reset notification behavior is + // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of + // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR. + return GL_NO_ERROR; + } - if (mResetStatus != GL_NO_ERROR) + // The GL_EXT_robustness spec says that if a reset is encountered, a reset + // status should be returned at least once, and GL_NO_ERROR should be returned + // once the device has finished resetting. + if (!mContextLost) { - ASSERT(mContextLost); + ASSERT(mResetStatus == GL_NO_ERROR); + mResetStatus = mImplementation->getResetStatus(); - if (mImplementation->testDeviceResettable()) + if (mResetStatus != GL_NO_ERROR) { - mResetStatus = GL_NO_ERROR; + mContextLost = true; } } + else if (!mContextLostForced && mResetStatus != GL_NO_ERROR) + { + // If markContextLost was used to mark the context lost then + // assume that is not recoverable, and continue to report the + // lost reset status for the lifetime of this context. + mResetStatus = mImplementation->getResetStatus(); + } - return status; + return mResetStatus; } bool Context::isResetNotificationEnabled() @@ -1612,13 +2100,36 @@ Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer) return framebufferIt->second; } +bool Context::isTextureGenerated(GLuint texture) const +{ + return mResourceManager->isTextureGenerated(texture); +} + +bool Context::isBufferGenerated(GLuint buffer) const +{ + return mResourceManager->isBufferGenerated(buffer); +} + +bool Context::isRenderbufferGenerated(GLuint renderbuffer) const +{ + return mResourceManager->isRenderbufferGenerated(renderbuffer); +} + +bool Context::isFramebufferGenerated(GLuint framebuffer) const +{ + ASSERT(mFramebufferMap.find(0) != mFramebufferMap.end()); + return mFramebufferMap.find(framebuffer) != mFramebufferMap.end(); +} + bool Context::isVertexArrayGenerated(GLuint vertexArray) { + ASSERT(mVertexArrayMap.find(0) != mVertexArrayMap.end()); return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end(); } bool Context::isTransformFeedbackGenerated(GLuint transformFeedback) { + ASSERT(mTransformFeedbackMap.find(0) != mTransformFeedbackMap.end()); return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end(); } @@ -1829,26 +2340,30 @@ void Context::initRendererString() mRendererString = MakeStaticString(rendererString.str()); } -const std::string &Context::getRendererString() const +const char *Context::getRendererString() const { return mRendererString; } void Context::initExtensionStrings() { - mExtensionStrings = mExtensions.getStrings(); + for (const auto &extensionString : mExtensions.getStrings()) + { + mExtensionStrings.push_back(MakeStaticString(extensionString)); + } std::ostringstream combinedStringStream; - std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator<std::string>(combinedStringStream, " ")); - mExtensionString = combinedStringStream.str(); + std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), + std::ostream_iterator<const char *>(combinedStringStream, " ")); + mExtensionString = MakeStaticString(combinedStringStream.str()); } -const std::string &Context::getExtensionString() const +const char *Context::getExtensionString() const { return mExtensionString; } -const std::string &Context::getExtensionString(size_t idx) const +const char *Context::getExtensionString(size_t idx) const { return mExtensionStrings[idx]; } @@ -1879,7 +2394,7 @@ bool Context::hasActiveTransformFeedback(GLuint program) const return false; } -void Context::initCaps() +void Context::initCaps(bool webGLContext) { mCaps = mImplementation->getNativeCaps(); @@ -1887,7 +2402,7 @@ void Context::initCaps() mLimitations = mImplementation->getNativeLimitations(); - if (mClientVersion < 3) + if (mClientMajorVersion < 3) { // Disable ES3+ extensions mExtensions.colorBufferFloat = false; @@ -1895,7 +2410,7 @@ void Context::initCaps() mExtensions.textureNorm16 = false; } - if (mClientVersion > 2) + if (mClientMajorVersion > 2) { // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts //mExtensions.sRGB = false; @@ -1904,6 +2419,7 @@ void Context::initCaps() // Some extensions are always available because they are implemented in the GL layer. mExtensions.bindUniformLocation = true; mExtensions.vertexArrayObject = true; + mExtensions.bindGeneratesResource = true; // Enable the no error extension if the context was created with the flag. mExtensions.noError = mSkipValidation; @@ -1915,6 +2431,9 @@ void Context::initCaps() mExtensions.maxDebugGroupStackDepth = 1024; mExtensions.maxLabelLength = 1024; + // Explicitly enable GL_ANGLE_robust_client_memory + mExtensions.robustClientMemory = true; + // Apply implementation limits mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); @@ -1922,7 +2441,25 @@ void Context::initCaps() mCaps.maxFragmentInputComponents = std::min<GLuint>(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); + // WebGL compatibility + mExtensions.webglCompatibility = webGLContext; + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + // If this context is for WebGL, disable all enableable extensions + if (webGLContext && extensionInfo.second.Enableable) + { + mExtensions.*(extensionInfo.second.ExtensionsMember) = false; + } + } + + // Generate texture caps + updateCaps(); +} + +void Context::updateCaps() +{ mCaps.compressedTextureFormats.clear(); + mTextureCaps.clear(); const TextureCapsMap &rendererFormats = mImplementation->getNativeTextureCaps(); for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++) @@ -1936,11 +2473,11 @@ void Context::initCaps() // Caps are AND'd with the renderer caps because some core formats are still unsupported in // ES3. formatCaps.texturable = - formatCaps.texturable && formatInfo.textureSupport(mClientVersion, mExtensions); + formatCaps.texturable && formatInfo.textureSupport(mClientMajorVersion, mExtensions); formatCaps.renderable = - formatCaps.renderable && formatInfo.renderSupport(mClientVersion, mExtensions); + formatCaps.renderable && formatInfo.renderSupport(mClientMajorVersion, mExtensions); formatCaps.filterable = - formatCaps.filterable && formatInfo.filterSupport(mClientVersion, mExtensions); + formatCaps.filterable && formatInfo.filterSupport(mClientMajorVersion, mExtensions); // OpenGL ES does not support multisampling with integer formats if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT) @@ -1957,6 +2494,13 @@ void Context::initCaps() } } +void Context::initWorkarounds() +{ + // Lose the context upon out of memory error if the application is + // expecting to watch for those events. + mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); +} + void Context::syncRendererState() { const State::DirtyBits &dirtyBits = mGLState.getDirtyBits(); @@ -2049,6 +2593,11 @@ void Context::readPixels(GLint x, GLenum type, GLvoid *pixels) { + if (width == 0 || height == 0) + { + return; + } + syncStateForReadPixels(); Framebuffer *framebufferObject = mGLState.getReadFramebuffer(); @@ -2087,6 +2636,11 @@ void Context::copyTexSubImage2D(GLenum target, GLsizei width, GLsizei height) { + if (width == 0 || height == 0) + { + return; + } + // Only sync the read FBO mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER); @@ -2109,6 +2663,11 @@ void Context::copyTexSubImage3D(GLenum target, GLsizei width, GLsizei height) { + if (width == 0 || height == 0) + { + return; + } + // Only sync the read FBO mGLState.syncDirtyObject(GL_READ_FRAMEBUFFER); @@ -2461,6 +3020,78 @@ void Context::generateMipmap(GLenum target) handleError(texture->generateMipmap()); } +GLboolean Context::enableExtension(const char *name) +{ + const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap(); + ASSERT(extensionInfos.find(name) != extensionInfos.end()); + const auto &extension = extensionInfos.at(name); + ASSERT(extension.Enableable); + + if (mExtensions.*(extension.ExtensionsMember)) + { + // Extension already enabled + return GL_TRUE; + } + + const auto &nativeExtensions = mImplementation->getNativeExtensions(); + if (!(nativeExtensions.*(extension.ExtensionsMember))) + { + // Underlying implementation does not support this valid extension + return GL_FALSE; + } + + mExtensions.*(extension.ExtensionsMember) = true; + updateCaps(); + initExtensionStrings(); + return GL_TRUE; +} + +void Context::copyTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + syncStateForTexImage(); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + handleError(destTexture->copyTexture(internalFormat, destType, unpackFlipY == GL_TRUE, + unpackPremultiplyAlpha == GL_TRUE, + unpackUnmultiplyAlpha == GL_TRUE, sourceTexture)); +} + +void Context::copySubTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + // Zero sized copies are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + syncStateForTexImage(); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + Offset offset(xoffset, yoffset, 0); + Rectangle area(x, y, width, height); + handleError(destTexture->copySubTexture(offset, area, unpackFlipY == GL_TRUE, + unpackPremultiplyAlpha == GL_TRUE, + unpackUnmultiplyAlpha == GL_TRUE, sourceTexture)); +} + void Context::getBufferPointerv(GLenum target, GLenum /*pname*/, void **params) { Buffer *buffer = mGLState.getTargetBuffer(target); @@ -2675,42 +3306,42 @@ void Context::pixelStorei(GLenum pname, GLint param) break; case GL_UNPACK_ROW_LENGTH: - ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage); + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage); mGLState.setUnpackRowLength(param); break; case GL_UNPACK_IMAGE_HEIGHT: - ASSERT(getClientVersion() >= 3); + ASSERT(getClientMajorVersion() >= 3); mGLState.setUnpackImageHeight(param); break; case GL_UNPACK_SKIP_IMAGES: - ASSERT(getClientVersion() >= 3); + ASSERT(getClientMajorVersion() >= 3); mGLState.setUnpackSkipImages(param); break; case GL_UNPACK_SKIP_ROWS: - ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage); + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage); mGLState.setUnpackSkipRows(param); break; case GL_UNPACK_SKIP_PIXELS: - ASSERT((getClientVersion() >= 3) || getExtensions().unpackSubimage); + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage); mGLState.setUnpackSkipPixels(param); break; case GL_PACK_ROW_LENGTH: - ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage); + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage); mGLState.setPackRowLength(param); break; case GL_PACK_SKIP_ROWS: - ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage); + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage); mGLState.setPackSkipRows(param); break; case GL_PACK_SKIP_PIXELS: - ASSERT((getClientVersion() >= 3) || getExtensions().packSubimage); + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage); mGLState.setPackSkipPixels(param); break; @@ -2921,4 +3552,28 @@ void Context::popDebugGroup() mGLState.getDebug().popGroup(); } +void Context::bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) +{ + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + handleError(buffer->bufferData(target, data, size, usage)); +} + +void Context::bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) +{ + if (data == nullptr) + { + return; + } + + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + handleError(buffer->bufferSubData(target, data, size, offset)); +} + +const Workarounds &Context::getWorkarounds() const +{ + return mWorkarounds; +} + } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/Context.h b/chromium/third_party/angle/src/libANGLE/Context.h index 8b6fb07d591..997c2da796f 100644 --- a/chromium/third_party/angle/src/libANGLE/Context.h +++ b/chromium/third_party/angle/src/libANGLE/Context.h @@ -22,6 +22,7 @@ #include "libANGLE/Error.h" #include "libANGLE/HandleAllocator.h" #include "libANGLE/VertexAttribute.h" +#include "libANGLE/Workarounds.h" #include "libANGLE/angletypes.h" namespace rx @@ -68,9 +69,6 @@ class Context final : public ValidationContext void makeCurrent(egl::Surface *surface); void releaseSurface(); - virtual void markContextLost(); - bool isContextLost(); - // These create and destroy methods are merely pass-throughs to // ResourceManager, which owns these object types GLuint createBuffer(); @@ -178,8 +176,14 @@ class Context final : public ValidationContext Query *getQuery(GLuint handle, bool create, GLenum type); Query *getQuery(GLuint handle) const; TransformFeedback *getTransformFeedback(GLuint handle) const; - LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; - LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; + void objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); + void objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label); + void getObjectLabel(GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label) const; + void getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) const; Texture *getTargetTexture(GLenum target) const; Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; @@ -188,6 +192,10 @@ class Context final : public ValidationContext bool isSampler(GLuint samplerName) const; + bool isTextureGenerated(GLuint texture) const; + bool isBufferGenerated(GLuint buffer) const; + bool isRenderbufferGenerated(GLuint renderbuffer) const; + bool isFramebufferGenerated(GLuint framebuffer) const; bool isVertexArrayGenerated(GLuint vertexArray); bool isTransformFeedbackGenerated(GLuint vertexArray); @@ -196,9 +204,9 @@ class Context final : public ValidationContext void getIntegerv(GLenum pname, GLint *params); void getInteger64v(GLenum pname, GLint64 *params); void getPointerv(GLenum pname, void **params) const; - - bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); - bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); + void getBooleani_v(GLenum target, GLuint index, GLboolean *data); + void getIntegeri_v(GLenum target, GLuint index, GLint *data); + void getInteger64i_v(GLenum target, GLuint index, GLint64 *data); void activeTexture(GLenum texture); void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); @@ -457,9 +465,29 @@ class Context final : public ValidationContext GLenum format, GLsizei imageSize, const GLvoid *data); + void copyTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + void copySubTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); void generateMipmap(GLenum target); + GLboolean enableExtension(const char *name); + Error flush(); Error finish(); @@ -491,24 +519,84 @@ class Context final : public ValidationContext void coverStrokePath(GLuint path, GLenum coverMode); void stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); void stencilThenCoverStrokePath(GLuint path, GLint reference, GLuint mask, GLenum coverMode); + void coverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void coverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void stencilFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBAse, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + void stencilStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + void stencilThenCoverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void stencilThenCoverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name); + void programPathFragmentInputGen(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + + void bufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); + void bufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); void handleError(const Error &error) override; GLenum getError(); + void markContextLost(); + bool isContextLost(); GLenum getResetStatus(); - virtual bool isResetNotificationEnabled(); + bool isResetNotificationEnabled(); const egl::Config *getConfig() const; EGLenum getClientType() const; EGLenum getRenderBuffer() const; - const std::string &getRendererString() const; + const char *getRendererString() const; - const std::string &getExtensionString() const; - const std::string &getExtensionString(size_t idx) const; + const char *getExtensionString() const; + const char *getExtensionString(size_t idx) const; size_t getExtensionStringCount() const; rx::ContextImpl *getImplementation() const { return mImplementation.get(); } + const Workarounds &getWorkarounds() const; private: void syncRendererState(); @@ -532,7 +620,12 @@ class Context final : public ValidationContext void initRendererString(); void initExtensionStrings(); - void initCaps(); + void initCaps(bool webGLContext); + void updateCaps(); + void initWorkarounds(); + + LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; + LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; std::unique_ptr<rx::ContextImpl> mImplementation; @@ -547,7 +640,8 @@ class Context final : public ValidationContext State mGLState; - int mClientVersion; + int mClientMajorVersion; + int mClientMinorVersion; const egl::Config *mConfig; EGLenum mClientType; @@ -569,9 +663,9 @@ class Context final : public ValidationContext ResourceMap<TransformFeedback> mTransformFeedbackMap; HandleAllocator mTransformFeedbackAllocator; - std::string mRendererString; - std::string mExtensionString; - std::vector<std::string> mExtensionStrings; + const char *mRendererString; + const char *mExtensionString; + std::vector<const char *> mExtensionStrings; // Recorded errors typedef std::set<GLenum> ErrorSet; @@ -581,6 +675,7 @@ class Context final : public ValidationContext bool mHasBeenCurrent; bool mContextLost; GLenum mResetStatus; + bool mContextLostForced; GLenum mResetStrategy; bool mRobustAccess; egl::Surface *mCurrentSurface; @@ -595,6 +690,8 @@ class Context final : public ValidationContext State::DirtyObjects mClearDirtyObjects; State::DirtyBits mBlitDirtyBits; State::DirtyObjects mBlitDirtyObjects; + + Workarounds mWorkarounds; }; } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/ContextState.cpp b/chromium/third_party/angle/src/libANGLE/ContextState.cpp index a824be5ceb3..56f8d9948b6 100644 --- a/chromium/third_party/angle/src/libANGLE/ContextState.cpp +++ b/chromium/third_party/angle/src/libANGLE/ContextState.cpp @@ -15,15 +15,16 @@ namespace gl { ContextState::ContextState(uintptr_t contextIn, - GLint clientVersionIn, + GLint clientMajorVersionIn, + GLint clientMinorVersionIn, State *stateIn, const Caps &capsIn, const TextureCapsMap &textureCapsIn, const Extensions &extensionsIn, const ResourceManager *resourceManagerIn, const Limitations &limitationsIn) - : mContext(contextIn), - mClientVersion(clientVersionIn), + : mGLVersion(clientMajorVersionIn, clientMinorVersionIn), + mContext(contextIn), mState(stateIn), mCaps(capsIn), mTextureCaps(textureCapsIn), @@ -42,7 +43,8 @@ const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const return mTextureCaps.get(internalFormat); } -ValidationContext::ValidationContext(GLint clientVersion, +ValidationContext::ValidationContext(GLint clientMajorVersion, + GLint clientMinorVersion, State *state, const Caps &caps, const TextureCapsMap &textureCaps, @@ -51,7 +53,8 @@ ValidationContext::ValidationContext(GLint clientVersion, const Limitations &limitations, bool skipValidation) : mState(reinterpret_cast<uintptr_t>(this), - clientVersion, + clientMajorVersion, + clientMinorVersion, state, caps, textureCaps, @@ -275,6 +278,14 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign *type = GL_INT; *numParams = 1; return true; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + if (!getExtensions().eglStreamConsumerExternal && !getExtensions().eglImageExternal) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; } if (getExtensions().debug) @@ -324,13 +335,24 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign } } + if (getExtensions().bindGeneratesResource) + { + switch (pname) + { + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + // Check for ES3.0+ parameter names which are also exposed as ES2 extensions switch (pname) { case GL_PACK_ROW_LENGTH: case GL_PACK_SKIP_ROWS: case GL_PACK_SKIP_PIXELS: - if ((getClientVersion() < 3) && !getExtensions().packSubimage) + if ((getClientMajorVersion() < 3) && !getExtensions().packSubimage) { return false; } @@ -340,7 +362,7 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign case GL_UNPACK_ROW_LENGTH: case GL_UNPACK_SKIP_ROWS: case GL_UNPACK_SKIP_PIXELS: - if ((getClientVersion() < 3) && !getExtensions().unpackSubimage) + if ((getClientMajorVersion() < 3) && !getExtensions().unpackSubimage) { return false; } @@ -348,7 +370,7 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign *numParams = 1; return true; case GL_VERTEX_ARRAY_BINDING: - if ((getClientVersion() < 3) && !getExtensions().vertexArrayObject) + if ((getClientMajorVersion() < 3) && !getExtensions().vertexArrayObject) { return false; } @@ -357,7 +379,7 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign return true; case GL_PIXEL_PACK_BUFFER_BINDING: case GL_PIXEL_UNPACK_BUFFER_BINDING: - if ((getClientVersion() < 3) && !getExtensions().pixelBufferObject) + if ((getClientMajorVersion() < 3) && !getExtensions().pixelBufferObject) { return false; } @@ -366,7 +388,9 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign return true; } - if (getClientVersion() < 3) + const GLVersion &glVersion = mState.getGLVersion(); + + if (!glVersion.isES3OrGreater()) { return false; } @@ -442,6 +466,63 @@ bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsign } } + if (!glVersion.isES31()) + { + return false; + } + + switch (pname) + { + case GL_MAX_FRAMEBUFFER_WIDTH: + case GL_MAX_FRAMEBUFFER_HEIGHT: + case GL_MAX_FRAMEBUFFER_SAMPLES: + case GL_MAX_SAMPLE_MASK_WORDS: + case GL_MAX_COLOR_TEXTURE_SAMPLES: + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + case GL_MAX_INTEGER_SAMPLES: + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + case GL_MAX_VERTEX_ATTRIB_STRIDE: + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET: + case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET: + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: + case GL_MAX_UNIFORM_LOCATIONS: + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + case GL_MAX_IMAGE_UNITS: + case GL_MAX_COMBINED_IMAGE_UNIFORMS: + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + } + return false; } @@ -449,7 +530,9 @@ bool ValidationContext::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) { - if (getClientVersion() < 3) + + const GLVersion &glVersion = mState.getGLVersion(); + if (!glVersion.isES3OrGreater()) { return false; } @@ -474,6 +557,22 @@ bool ValidationContext::getIndexedQueryParameterInfo(GLenum target, } } + if (!glVersion.isES31()) + { + return false; + } + + switch (target) + { + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + { + *type = GL_INT; + *numParams = 1; + return true; + } + } + return false; } diff --git a/chromium/third_party/angle/src/libANGLE/ContextState.h b/chromium/third_party/angle/src/libANGLE/ContextState.h index a4c51094280..ecb3759f483 100644 --- a/chromium/third_party/angle/src/libANGLE/ContextState.h +++ b/chromium/third_party/angle/src/libANGLE/ContextState.h @@ -15,12 +15,35 @@ namespace gl { class ValidationContext; +class ContextState; + +class GLVersion final : angle::NonCopyable +{ + public: + GLVersion(GLint clientMajorVersion, GLint clientMinorVersion) + : mClientMajorVersion(clientMajorVersion), mClientMinorVersion(clientMinorVersion) + { + } + + GLint getClientMajorVersion() const { return mClientMajorVersion; } + GLint getClientMinorVersion() const { return mClientMinorVersion; } + + bool isES2() const { return mClientMajorVersion == 2; } + bool isES3() const { return mClientMajorVersion == 3 && mClientMinorVersion == 0; } + bool isES31() const { return mClientMajorVersion == 3 && mClientMinorVersion == 1; } + bool isES3OrGreater() const { return mClientMajorVersion >= 3; } + + private: + GLint mClientMajorVersion; + GLint mClientMinorVersion; +}; class ContextState final : public angle::NonCopyable { public: ContextState(uintptr_t context, - GLint clientVersion, + GLint clientMajorVersion, + GLint clientMinorVersion, State *state, const Caps &caps, const TextureCapsMap &textureCaps, @@ -30,7 +53,9 @@ class ContextState final : public angle::NonCopyable ~ContextState(); uintptr_t getContext() const { return mContext; } - GLint getClientVersion() const { return mClientVersion; } + GLint getClientMajorVersion() const { return mGLVersion.getClientMajorVersion(); } + GLint getClientMinorVersion() const { return mGLVersion.getClientMinorVersion(); } + const GLVersion &getGLVersion() const { return mGLVersion; } const State &getState() const { return *mState; } const Caps &getCaps() const { return mCaps; } const TextureCapsMap &getTextureCaps() const { return mTextureCaps; } @@ -44,8 +69,8 @@ class ContextState final : public angle::NonCopyable friend class Context; friend class ValidationContext; + GLVersion mGLVersion; uintptr_t mContext; - GLint mClientVersion; State *mState; const Caps &mCaps; const TextureCapsMap &mTextureCaps; @@ -57,7 +82,8 @@ class ContextState final : public angle::NonCopyable class ValidationContext : angle::NonCopyable { public: - ValidationContext(GLint clientVersion, + ValidationContext(GLint clientMajorVersion, + GLint clientMinorVersion, State *state, const Caps &caps, const TextureCapsMap &textureCaps, @@ -70,7 +96,9 @@ class ValidationContext : angle::NonCopyable virtual void handleError(const Error &error) = 0; const ContextState &getContextState() const { return mState; } - int getClientVersion() const { return mState.getClientVersion(); } + int getClientMajorVersion() const { return mState.getClientMajorVersion(); } + int getClientMinorVersion() const { return mState.getClientMinorVersion(); } + const GLVersion &getGLVersion() const { return mState.mGLVersion; } const State &getGLState() const { return mState.getState(); } const Caps &getCaps() const { return mState.getCaps(); } const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } diff --git a/chromium/third_party/angle/src/libANGLE/Display.cpp b/chromium/third_party/angle/src/libANGLE/Display.cpp index 1f9d6c3980b..92d7ddaa054 100644 --- a/chromium/third_party/angle/src/libANGLE/Display.cpp +++ b/chromium/third_party/angle/src/libANGLE/Display.cpp @@ -53,6 +53,10 @@ # endif #endif +#if defined(ANGLE_ENABLE_NULL) +#include "libANGLE/renderer/null/DisplayNULL.h" +#endif + namespace egl { @@ -209,6 +213,12 @@ rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap) break; #endif +#if defined(ANGLE_ENABLE_NULL) + case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: + impl = new rx::DisplayNULL(); + break; +#endif + default: UNREACHABLE(); break; @@ -321,6 +331,7 @@ Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDe mContextSet(), mStreamSet(), mInitialized(false), + mDeviceLost(false), mCaps(), mDisplayExtensions(), mDisplayExtensionString(), @@ -773,21 +784,34 @@ void Display::destroyContext(gl::Context *context) bool Display::isDeviceLost() const { ASSERT(isInitialized()); - return mImplementation->isDeviceLost(); + return mDeviceLost; } bool Display::testDeviceLost() { ASSERT(isInitialized()); - return mImplementation->testDeviceLost(); + + if (!mDeviceLost && mImplementation->testDeviceLost()) + { + notifyDeviceLost(); + } + + return mDeviceLost; } void Display::notifyDeviceLost() { + if (mDeviceLost) + { + return; + } + for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++) { (*context)->markContextLost(); } + + mDeviceLost = true; } Error Display::waitClient() const @@ -860,6 +884,10 @@ static ClientExtensions GenerateClientExtensions() extensions.platformANGLEOpenGL = true; #endif +#if defined(ANGLE_ENABLE_NULL) + extensions.platformANGLENULL = true; +#endif + #if defined(ANGLE_ENABLE_D3D11) extensions.deviceCreation = true; extensions.deviceCreationD3D11 = true; @@ -904,6 +932,8 @@ void Display::initDisplayExtensions() // Some extensions are always available because they are implemented in the EGL layer. mDisplayExtensions.createContext = true; mDisplayExtensions.createContextNoError = true; + mDisplayExtensions.createContextWebGLCompatibility = true; + mDisplayExtensions.createContextBindGeneratesResource = true; // Force EGL_KHR_get_all_proc_addresses on. mDisplayExtensions.getAllProcAddresses = true; @@ -985,4 +1015,8 @@ Device *Display::getDevice() const return mDevice; } +gl::Version Display::getMaxSupportedESVersion() const +{ + return mImplementation->getMaxSupportedESVersion(); +} } diff --git a/chromium/third_party/angle/src/libANGLE/Display.h b/chromium/third_party/angle/src/libANGLE/Display.h index a926ed6a4e0..c0dafb90f3b 100644 --- a/chromium/third_party/angle/src/libANGLE/Display.h +++ b/chromium/third_party/angle/src/libANGLE/Display.h @@ -14,10 +14,11 @@ #include <set> #include <vector> -#include "libANGLE/Error.h" +#include "libANGLE/AttributeMap.h" #include "libANGLE/Caps.h" #include "libANGLE/Config.h" -#include "libANGLE/AttributeMap.h" +#include "libANGLE/Error.h" +#include "libANGLE/Version.h" namespace gl { @@ -111,6 +112,8 @@ class Display final : angle::NonCopyable Device *getDevice() const; EGLenum getPlatform() const { return mPlatform; } + gl::Version getMaxSupportedESVersion() const; + private: Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice); @@ -138,6 +141,7 @@ class Display final : angle::NonCopyable StreamSet mStreamSet; bool mInitialized; + bool mDeviceLost; Caps mCaps; diff --git a/chromium/third_party/angle/src/libANGLE/Framebuffer.cpp b/chromium/third_party/angle/src/libANGLE/Framebuffer.cpp index 75627f02ffb..4bb21385491 100644 --- a/chromium/third_party/angle/src/libANGLE/Framebuffer.cpp +++ b/chromium/third_party/angle/src/libANGLE/Framebuffer.cpp @@ -218,6 +218,37 @@ size_t FramebufferState::getDrawBufferCount() const return mDrawBufferStates.size(); } +bool FramebufferState::colorAttachmentsAreUniqueImages() const +{ + for (size_t firstAttachmentIdx = 0; firstAttachmentIdx < mColorAttachments.size(); + firstAttachmentIdx++) + { + const gl::FramebufferAttachment &firstAttachment = mColorAttachments[firstAttachmentIdx]; + if (!firstAttachment.isAttached()) + { + continue; + } + + for (size_t secondAttachmentIdx = firstAttachmentIdx + 1; + secondAttachmentIdx < mColorAttachments.size(); secondAttachmentIdx++) + { + const gl::FramebufferAttachment &secondAttachment = + mColorAttachments[secondAttachmentIdx]; + if (!secondAttachment.isAttached()) + { + continue; + } + + if (firstAttachment == secondAttachment) + { + return false; + } + } + } + + return true; +} + Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id) : mState(caps), mImpl(factory->createFramebuffer(mState)), @@ -469,9 +500,8 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - GLenum internalformat = colorAttachment.getInternalFormat(); - const TextureCaps &formatCaps = state.getTextureCap(internalformat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); + const Format &format = colorAttachment.getFormat(); + const TextureCaps &formatCaps = state.getTextureCap(format.asSized()); if (colorAttachment.type() == GL_TEXTURE) { if (!formatCaps.renderable) @@ -479,7 +509,7 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) + if (format.info->depthBits > 0 || format.info->stencilBits > 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -503,7 +533,8 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) } else if (colorAttachment.type() == GL_RENDERBUFFER) { - if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) + if (!formatCaps.renderable || format.info->depthBits > 0 || + format.info->stencilBits > 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -520,9 +551,9 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) // in GLES 2.0, all color attachments attachments must have the same number of bitplanes // in GLES 3.0, there is no such restriction - if (state.getClientVersion() < 3) + if (state.getClientMajorVersion() < 3) { - if (formatInfo.pixelBytes != colorbufferSize) + if (format.info->pixelBytes != colorbufferSize) { return GL_FRAMEBUFFER_UNSUPPORTED; } @@ -531,7 +562,7 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) else { samples = colorAttachment.getSamples(); - colorbufferSize = formatInfo.pixelBytes; + colorbufferSize = format.info->pixelBytes; missingAttachment = false; } } @@ -546,9 +577,8 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - GLenum internalformat = depthAttachment.getInternalFormat(); - const TextureCaps &formatCaps = state.getTextureCap(internalformat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); + const Format &format = depthAttachment.getFormat(); + const TextureCaps &formatCaps = state.getTextureCap(format.asSized()); if (depthAttachment.type() == GL_TEXTURE) { // depth texture attachments require OES/ANGLE_depth_texture @@ -562,14 +592,14 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (formatInfo.depthBits == 0) + if (format.info->depthBits == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } else if (depthAttachment.type() == GL_RENDERBUFFER) { - if (!formatCaps.renderable || formatInfo.depthBits == 0) + if (!formatCaps.renderable || format.info->depthBits == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -605,9 +635,8 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - GLenum internalformat = stencilAttachment.getInternalFormat(); - const TextureCaps &formatCaps = state.getTextureCap(internalformat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); + const Format &format = stencilAttachment.getFormat(); + const TextureCaps &formatCaps = state.getTextureCap(format.asSized()); if (stencilAttachment.type() == GL_TEXTURE) { // texture stencil attachments come along as part @@ -622,14 +651,14 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (formatInfo.stencilBits == 0) + if (format.info->stencilBits == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } else if (stencilAttachment.type() == GL_RENDERBUFFER) { - if (!formatCaps.renderable || formatInfo.stencilBits == 0) + if (!formatCaps.renderable || format.info->stencilBits == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } @@ -654,7 +683,7 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) } // Starting from ES 3.0 stencil and depth, if present, should be the same image - if (state.getClientVersion() >= 3 && depthAttachment.isAttached() && + if (state.getClientMajorVersion() >= 3 && depthAttachment.isAttached() && stencilAttachment != depthAttachment) { return GL_FRAMEBUFFER_UNSUPPORTED; @@ -669,7 +698,7 @@ GLenum Framebuffer::checkStatusImpl(const ContextState &state) // In ES 2.0, all color attachments must have the same width and height. // In ES 3.0, there is no such restriction. - if (state.getClientVersion() < 3 && !mState.attachmentsHaveSameDimensions()) + if (state.getClientMajorVersion() < 3 && !mState.attachmentsHaveSameDimensions()) { return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } @@ -831,9 +860,8 @@ void Framebuffer::setAttachment(GLenum type, if (resource) { FramebufferAttachment::Target target(binding, textureIndex); - GLenum internalFormat = resource->getAttachmentInternalFormat(target); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat); - if (formatInfo.depthBits == 0 || formatInfo.stencilBits == 0) + const Format &format = resource->getAttachmentFormat(target); + if (format.info->depthBits == 0 || format.info->stencilBits == 0) { // Attaching nullptr detaches the current attachment. attachmentObj = nullptr; diff --git a/chromium/third_party/angle/src/libANGLE/Framebuffer.h b/chromium/third_party/angle/src/libANGLE/Framebuffer.h index f55879383e5..db0d6215f37 100644 --- a/chromium/third_party/angle/src/libANGLE/Framebuffer.h +++ b/chromium/third_party/angle/src/libANGLE/Framebuffer.h @@ -75,6 +75,7 @@ class FramebufferState final : angle::NonCopyable } bool attachmentsHaveSameDimensions() const; + bool colorAttachmentsAreUniqueImages() const; const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const; size_t getDrawBufferCount() const; diff --git a/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.cpp b/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.cpp index b1c5b9024ec..37af254f241 100644 --- a/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.cpp +++ b/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.cpp @@ -115,42 +115,42 @@ void FramebufferAttachment::attach(GLenum type, GLuint FramebufferAttachment::getRedSize() const { - return GetInternalFormatInfo(getInternalFormat()).redBits; + return getFormat().info->redBits; } GLuint FramebufferAttachment::getGreenSize() const { - return GetInternalFormatInfo(getInternalFormat()).greenBits; + return getFormat().info->greenBits; } GLuint FramebufferAttachment::getBlueSize() const { - return GetInternalFormatInfo(getInternalFormat()).blueBits; + return getFormat().info->blueBits; } GLuint FramebufferAttachment::getAlphaSize() const { - return GetInternalFormatInfo(getInternalFormat()).alphaBits; + return getFormat().info->alphaBits; } GLuint FramebufferAttachment::getDepthSize() const { - return GetInternalFormatInfo(getInternalFormat()).depthBits; + return getFormat().info->depthBits; } GLuint FramebufferAttachment::getStencilSize() const { - return GetInternalFormatInfo(getInternalFormat()).stencilBits; + return getFormat().info->stencilBits; } GLenum FramebufferAttachment::getComponentType() const { - return GetInternalFormatInfo(getInternalFormat()).componentType; + return getFormat().info->componentType; } GLenum FramebufferAttachment::getColorEncoding() const { - return GetInternalFormatInfo(getInternalFormat()).colorEncoding; + return getFormat().info->colorEncoding; } GLuint FramebufferAttachment::id() const diff --git a/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.h b/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.h index bbce8958336..41502737de9 100644 --- a/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.h +++ b/chromium/third_party/angle/src/libANGLE/FramebufferAttachment.h @@ -39,6 +39,7 @@ class FramebufferAttachmentObjectImpl; namespace gl { class FramebufferAttachmentObject; +struct Format; class Renderbuffer; class Texture; @@ -117,7 +118,7 @@ class FramebufferAttachment final // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and // Renderbuffers, it will always be 1. Extents getSize() const; - GLenum getInternalFormat() const; + const Format &getFormat() const; GLsizei getSamples() const; GLenum type() const { return mType; } bool isAttached() const { return mType != GL_NONE; } @@ -156,7 +157,8 @@ class FramebufferAttachmentObject virtual ~FramebufferAttachmentObject() {} virtual Extents getAttachmentSize(const FramebufferAttachment::Target &target) const = 0; - virtual GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &target) const = 0; + virtual const Format &getAttachmentFormat( + const FramebufferAttachment::Target &target) const = 0; virtual GLsizei getAttachmentSamples(const FramebufferAttachment::Target &target) const = 0; virtual void onAttach() = 0; @@ -179,9 +181,9 @@ inline Extents FramebufferAttachment::getSize() const return mResource->getAttachmentSize(mTarget); } -inline GLenum FramebufferAttachment::getInternalFormat() const +inline const Format &FramebufferAttachment::getFormat() const { - return mResource->getAttachmentInternalFormat(mTarget); + return mResource->getAttachmentFormat(mTarget); } inline GLsizei FramebufferAttachment::getSamples() const diff --git a/chromium/third_party/angle/src/libANGLE/Image.cpp b/chromium/third_party/angle/src/libANGLE/Image.cpp index a9448e3f6c8..828f8623895 100644 --- a/chromium/third_party/angle/src/libANGLE/Image.cpp +++ b/chromium/third_party/angle/src/libANGLE/Image.cpp @@ -11,6 +11,7 @@ #include "common/debug.h" #include "common/utilities.h" #include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" #include "libANGLE/Texture.h" #include "libANGLE/Renderbuffer.h" #include "libANGLE/renderer/ImageImpl.h" @@ -82,7 +83,7 @@ void ImageSibling::removeImageSource(egl::Image *imageSource) Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) : RefCountObject(0), mImplementation(impl), - mInternalFormat(GL_NONE), + mFormat(gl::Format::Invalid()), mWidth(0), mHeight(0), mSamples(0), @@ -100,7 +101,7 @@ Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const At gl::Texture *texture = rx::GetAs<gl::Texture>(mSource.get()); GLenum textureTarget = egl_gl::EGLImageTargetToGLTextureTarget(target); size_t level = attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); - mInternalFormat = texture->getInternalFormat(textureTarget, level); + mFormat = texture->getFormat(textureTarget, level); mWidth = texture->getWidth(textureTarget, level); mHeight = texture->getHeight(textureTarget, level); mSamples = 0; @@ -108,7 +109,7 @@ Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const At else if (IsRenderbufferTarget(target)) { gl::Renderbuffer *renderbuffer = rx::GetAs<gl::Renderbuffer>(mSource.get()); - mInternalFormat = renderbuffer->getInternalFormat(); + mFormat = renderbuffer->getFormat(); mWidth = renderbuffer->getWidth(); mHeight = renderbuffer->getHeight(); mSamples = renderbuffer->getSamples(); @@ -160,9 +161,9 @@ gl::Error Image::orphanSibling(ImageSibling *sibling) return error; } -GLenum Image::getInternalFormat() const +const gl::Format &Image::getFormat() const { - return mInternalFormat; + return mFormat; } size_t Image::getWidth() const @@ -189,4 +190,4 @@ const rx::ImageImpl *Image::getImplementation() const { return mImplementation; } -} +} // namespace egl diff --git a/chromium/third_party/angle/src/libANGLE/Image.h b/chromium/third_party/angle/src/libANGLE/Image.h index 26c9df914c6..a579beab274 100644 --- a/chromium/third_party/angle/src/libANGLE/Image.h +++ b/chromium/third_party/angle/src/libANGLE/Image.h @@ -13,6 +13,7 @@ #include "libANGLE/AttributeMap.h" #include "libANGLE/Error.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/formatutils.h" #include <set> @@ -57,7 +58,7 @@ class Image final : public RefCountObject Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); ~Image(); - GLenum getInternalFormat() const; + const gl::Format &getFormat() const; size_t getWidth() const; size_t getHeight() const; size_t getSamples() const; @@ -78,7 +79,7 @@ class Image final : public RefCountObject rx::ImageImpl *mImplementation; - GLenum mInternalFormat; + gl::Format mFormat; size_t mWidth; size_t mHeight; size_t mSamples; diff --git a/chromium/third_party/angle/src/libANGLE/ImageIndex.cpp b/chromium/third_party/angle/src/libANGLE/ImageIndex.cpp index 38c1941a350..f74ce19d90d 100644 --- a/chromium/third_party/angle/src/libANGLE/ImageIndex.cpp +++ b/chromium/third_party/angle/src/libANGLE/ImageIndex.cpp @@ -135,7 +135,12 @@ ImageIndexIterator::ImageIndexIterator(GLenum type, const Range<GLint> &mipRange GLint ImageIndexIterator::maxLayer() const { - return (mLayerCounts ? static_cast<GLint>(mLayerCounts[mCurrentMip]) : mLayerRange.end); + if (mLayerCounts) + { + ASSERT(mCurrentMip >= 0); + return (mCurrentMip < mMipRange.end) ? mLayerCounts[mCurrentMip] : 0; + } + return mLayerRange.end; } ImageIndex ImageIndexIterator::next() @@ -149,21 +154,29 @@ ImageIndex ImageIndexIterator::next() if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL) { - if (mCurrentLayer < maxLayer()-1) + if (mCurrentLayer < maxLayer() - 1) { mCurrentLayer++; } - else if (mCurrentMip < mMipRange.end-1) + else if (mCurrentMip < mMipRange.end - 1) { mCurrentMip++; mCurrentLayer = mLayerRange.start; } + else + { + done(); + } } - else if (mCurrentMip < mMipRange.end-1) + else if (mCurrentMip < mMipRange.end - 1) { mCurrentMip++; mCurrentLayer = mLayerRange.start; } + else + { + done(); + } return value; } @@ -185,4 +198,10 @@ bool ImageIndexIterator::hasNext() const return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer()); } +void ImageIndexIterator::done() +{ + mCurrentMip = mMipRange.end; + mCurrentLayer = maxLayer(); } + +} // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/ImageIndex.h b/chromium/third_party/angle/src/libANGLE/ImageIndex.h index 52ac40c45af..5961f0cb046 100644 --- a/chromium/third_party/angle/src/libANGLE/ImageIndex.h +++ b/chromium/third_party/angle/src/libANGLE/ImageIndex.h @@ -68,6 +68,7 @@ class ImageIndexIterator const Range<GLint> &layerRange, const GLsizei *layerCounts); GLint maxLayer() const; + void done(); GLenum mType; Range<GLint> mMipRange; diff --git a/chromium/third_party/angle/src/libANGLE/ImageIndexIterator_unittest.cpp b/chromium/third_party/angle/src/libANGLE/ImageIndexIterator_unittest.cpp index 2dc0b2ab7f8..2f97e8eba95 100644 --- a/chromium/third_party/angle/src/libANGLE/ImageIndexIterator_unittest.cpp +++ b/chromium/third_party/angle/src/libANGLE/ImageIndexIterator_unittest.cpp @@ -41,6 +41,8 @@ TEST(ImageIndexTest, Iterator2D) EXPECT_EQ(current.mipIndex, nextIndex.mipIndex); EXPECT_EQ(current.layerIndex, nextIndex.layerIndex); } + + EXPECT_FALSE(iter.hasNext()); } TEST(ImageIndexTest, IteratorCube) @@ -64,6 +66,8 @@ TEST(ImageIndexTest, IteratorCube) EXPECT_TRUE(nextIndex.hasLayer()); } } + + EXPECT_FALSE(iter.hasNext()); } TEST(ImageIndexTest, Iterator3D) @@ -85,6 +89,8 @@ TEST(ImageIndexTest, Iterator3D) EXPECT_TRUE(nextIndex.hasLayer()); } } + + EXPECT_FALSE(iter.hasNext()); } TEST(ImageIndexTest, Iterator2DArray) @@ -109,6 +115,8 @@ TEST(ImageIndexTest, Iterator2DArray) EXPECT_TRUE(nextIndex.hasLayer()); } } + + EXPECT_FALSE(iter.hasNext()); } } // namespace diff --git a/chromium/third_party/angle/src/libANGLE/Program.cpp b/chromium/third_party/angle/src/libANGLE/Program.cpp index dc56af3bd36..29be350feaa 100644 --- a/chromium/third_party/angle/src/libANGLE/Program.cpp +++ b/chromium/third_party/angle/src/libANGLE/Program.cpp @@ -177,7 +177,7 @@ void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const } // append a santized message to the program info log. -// The D3D compiler includes a fake file path in some of the warning or error +// The D3D compiler includes a fake file path in some of the warning or error // messages, so lets remove all occurrences of this fake file path from the log. void InfoLog::appendSanitized(const char *message) { @@ -237,9 +237,11 @@ ProgramState::ProgramState() : mLabel(), mAttachedFragmentShader(nullptr), mAttachedVertexShader(nullptr), + mAttachedComputeShader(nullptr), mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS), mBinaryRetrieveableHint(false) { + mComputeShaderLocalSize.fill(1); } ProgramState::~ProgramState() @@ -253,6 +255,11 @@ ProgramState::~ProgramState() { mAttachedFragmentShader->release(); } + + if (mAttachedComputeShader != nullptr) + { + mAttachedComputeShader->release(); + } } const std::string &ProgramState::getLabel() @@ -372,61 +379,96 @@ const std::string &Program::getLabel() const bool Program::attachShader(Shader *shader) { - if (shader->getType() == GL_VERTEX_SHADER) + switch (shader->getType()) { - if (mState.mAttachedVertexShader) + case GL_VERTEX_SHADER: { - return false; - } + if (mState.mAttachedVertexShader) + { + return false; + } - mState.mAttachedVertexShader = shader; - mState.mAttachedVertexShader->addRef(); - } - else if (shader->getType() == GL_FRAGMENT_SHADER) - { - if (mState.mAttachedFragmentShader) + mState.mAttachedVertexShader = shader; + mState.mAttachedVertexShader->addRef(); + break; + } + case GL_FRAGMENT_SHADER: { - return false; + if (mState.mAttachedFragmentShader) + { + return false; + } + + mState.mAttachedFragmentShader = shader; + mState.mAttachedFragmentShader->addRef(); + break; } + case GL_COMPUTE_SHADER: + { + if (mState.mAttachedComputeShader) + { + return false; + } - mState.mAttachedFragmentShader = shader; - mState.mAttachedFragmentShader->addRef(); + mState.mAttachedComputeShader = shader; + mState.mAttachedComputeShader->addRef(); + break; + } + default: + UNREACHABLE(); } - else UNREACHABLE(); return true; } bool Program::detachShader(Shader *shader) { - if (shader->getType() == GL_VERTEX_SHADER) + switch (shader->getType()) { - if (mState.mAttachedVertexShader != shader) + case GL_VERTEX_SHADER: { - return false; - } + if (mState.mAttachedVertexShader != shader) + { + return false; + } - shader->release(); - mState.mAttachedVertexShader = nullptr; - } - else if (shader->getType() == GL_FRAGMENT_SHADER) - { - if (mState.mAttachedFragmentShader != shader) + shader->release(); + mState.mAttachedVertexShader = nullptr; + break; + } + case GL_FRAGMENT_SHADER: { - return false; + if (mState.mAttachedFragmentShader != shader) + { + return false; + } + + shader->release(); + mState.mAttachedFragmentShader = nullptr; + break; } + case GL_COMPUTE_SHADER: + { + if (mState.mAttachedComputeShader != shader) + { + return false; + } - shader->release(); - mState.mAttachedFragmentShader = nullptr; + shader->release(); + mState.mAttachedComputeShader = nullptr; + break; + } + default: + UNREACHABLE(); } - else UNREACHABLE(); return true; } int Program::getAttachedShadersCount() const { - return (mState.mAttachedVertexShader ? 1 : 0) + (mState.mAttachedFragmentShader ? 1 : 0); + return (mState.mAttachedVertexShader ? 1 : 0) + (mState.mAttachedFragmentShader ? 1 : 0) + + (mState.mAttachedComputeShader ? 1 : 0); } void Program::bindAttributeLocation(GLuint index, const char *name) @@ -440,9 +482,85 @@ void Program::bindUniformLocation(GLuint index, const char *name) mUniformBindings.bindLocation(index, ParseUniformName(name, nullptr)); } -// Links the HLSL code of the vertex and pixel shader by matching up their varyings, -// compiling them into binaries, determining the attribute mappings, and collecting -// a list of uniforms +void Program::bindFragmentInputLocation(GLint index, const char *name) +{ + mFragmentInputBindings.bindLocation(index, name); +} + +BindingInfo Program::getFragmentInputBindingInfo(GLint index) const +{ + BindingInfo ret; + ret.type = GL_NONE; + ret.valid = false; + + const Shader *fragmentShader = mState.getAttachedFragmentShader(); + ASSERT(fragmentShader); + + // Find the actual fragment shader varying we're interested in + const std::vector<sh::Varying> &inputs = fragmentShader->getVaryings(); + + for (const auto &binding : mFragmentInputBindings) + { + if (binding.second != static_cast<GLuint>(index)) + continue; + + ret.valid = true; + + std::string originalName = binding.first; + unsigned int arrayIndex = ParseAndStripArrayIndex(&originalName); + + for (const auto &in : inputs) + { + if (in.name == originalName) + { + if (in.isArray()) + { + // The client wants to bind either "name" or "name[0]". + // GL ES 3.1 spec refers to active array names with language such as: + // "if the string identifies the base name of an active array, where the + // string would exactly match the name of the variable if the suffix "[0]" + // were appended to the string". + if (arrayIndex == GL_INVALID_INDEX) + arrayIndex = 0; + + ret.name = in.mappedName + "[" + ToString(arrayIndex) + "]"; + } + else + { + ret.name = in.mappedName; + } + ret.type = in.type; + return ret; + } + } + } + + return ret; +} + +void Program::pathFragmentInputGen(GLint index, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + // If the location is -1 then the command is silently ignored + if (index == -1) + return; + + const auto &binding = getFragmentInputBindingInfo(index); + + // If the input doesn't exist then then the command is silently ignored + // This could happen through optimization for example, the shader translator + // decides that a variable is not actually being used and optimizes it away. + if (binding.name.empty()) + return; + + mProgram->setPathFragmentInputGen(binding.name, genMode, components, coeffs); +} + +// The attached shaders are checked for linking errors by matching up their variables. +// Uniform, input and output variables get collected. +// The code gets compiled into binaries. Error Program::link(const ContextState &data) { unlink(false); @@ -450,65 +568,119 @@ Error Program::link(const ContextState &data) mInfoLog.reset(); resetUniformBlockBindings(); - if (!mState.mAttachedFragmentShader || !mState.mAttachedFragmentShader->isCompiled()) - { - return Error(GL_NO_ERROR); - } - ASSERT(mState.mAttachedFragmentShader->getType() == GL_FRAGMENT_SHADER); + const Caps &caps = data.getCaps(); - if (!mState.mAttachedVertexShader || !mState.mAttachedVertexShader->isCompiled()) + bool isComputeShaderAttached = (mState.mAttachedComputeShader != nullptr); + bool nonComputeShadersAttached = + (mState.mAttachedVertexShader != nullptr || mState.mAttachedFragmentShader != nullptr); + // Check whether we both have a compute and non-compute shaders attached. + // If there are of both types attached, then linking should fail. + // OpenGL ES 3.10, 7.3 Program Objects, under LinkProgram + if (isComputeShaderAttached == true && nonComputeShadersAttached == true) { - return Error(GL_NO_ERROR); + mInfoLog << "Both a compute and non-compute shaders are attached to the same program."; + return NoError(); } - ASSERT(mState.mAttachedVertexShader->getType() == GL_VERTEX_SHADER); - if (mState.mAttachedFragmentShader->getShaderVersion() != - mState.mAttachedVertexShader->getShaderVersion()) + if (mState.mAttachedComputeShader) { - mInfoLog << "Fragment shader version does not match vertex shader version."; - return Error(GL_NO_ERROR); - } + if (!mState.mAttachedComputeShader->isCompiled()) + { + mInfoLog << "Attached compute shader is not compiled."; + return NoError(); + } + ASSERT(mState.mAttachedComputeShader->getType() == GL_COMPUTE_SHADER); - if (!linkAttributes(data, mInfoLog, mAttributeBindings, mState.mAttachedVertexShader)) - { - return Error(GL_NO_ERROR); - } + mState.mComputeShaderLocalSize = mState.mAttachedComputeShader->getWorkGroupSize(); - if (!linkVaryings(mInfoLog, mState.mAttachedVertexShader, mState.mAttachedFragmentShader)) - { - return Error(GL_NO_ERROR); - } + // GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs + // If the work group size is not specified, a link time error should occur. + if (!mState.mComputeShaderLocalSize.isDeclared()) + { + mInfoLog << "Work group size is not specified."; + return NoError(); + } - if (!linkUniforms(mInfoLog, data.getCaps(), mUniformBindings)) - { - return Error(GL_NO_ERROR); - } + if (!linkUniforms(mInfoLog, caps, mUniformBindings)) + { + return NoError(); + } - if (!linkUniformBlocks(mInfoLog, data.getCaps())) - { - return Error(GL_NO_ERROR); - } + if (!linkUniformBlocks(mInfoLog, caps)) + { + return NoError(); + } - const auto &mergedVaryings = getMergedVaryings(); + rx::LinkResult result = mProgram->link(data, mInfoLog); - if (!linkValidateTransformFeedback(mInfoLog, mergedVaryings, data.getCaps())) - { - return Error(GL_NO_ERROR); + if (result.error.isError() || !result.linkSuccess) + { + return result.error; + } } + else + { + if (!mState.mAttachedFragmentShader || !mState.mAttachedFragmentShader->isCompiled()) + { + return NoError(); + } + ASSERT(mState.mAttachedFragmentShader->getType() == GL_FRAGMENT_SHADER); - linkOutputVariables(); + if (!mState.mAttachedVertexShader || !mState.mAttachedVertexShader->isCompiled()) + { + return NoError(); + } + ASSERT(mState.mAttachedVertexShader->getType() == GL_VERTEX_SHADER); - rx::LinkResult result = mProgram->link(data, mInfoLog); - if (result.error.isError() || !result.linkSuccess) - { - return result.error; + if (mState.mAttachedFragmentShader->getShaderVersion() != + mState.mAttachedVertexShader->getShaderVersion()) + { + mInfoLog << "Fragment shader version does not match vertex shader version."; + return NoError(); + } + + if (!linkAttributes(data, mInfoLog, mAttributeBindings, mState.mAttachedVertexShader)) + { + return NoError(); + } + + if (!linkVaryings(mInfoLog, mState.mAttachedVertexShader, mState.mAttachedFragmentShader)) + { + return NoError(); + } + + if (!linkUniforms(mInfoLog, caps, mUniformBindings)) + { + return NoError(); + } + + if (!linkUniformBlocks(mInfoLog, caps)) + { + return NoError(); + } + + const auto &mergedVaryings = getMergedVaryings(); + + if (!linkValidateTransformFeedback(mInfoLog, mergedVaryings, caps)) + { + return NoError(); + } + + linkOutputVariables(); + + rx::LinkResult result = mProgram->link(data, mInfoLog); + if (result.error.isError() || !result.linkSuccess) + { + return result.error; + } + + gatherTransformFeedbackVaryings(mergedVaryings); } - gatherTransformFeedbackVaryings(mergedVaryings); gatherInterfaceBlockInfo(); mLinked = true; - return gl::Error(GL_NO_ERROR); + return NoError(); } // Returns the program object to an unlinked state, before re-linking, or at destruction @@ -527,6 +699,12 @@ void Program::unlink(bool destroy) mState.mAttachedVertexShader->release(); mState.mAttachedVertexShader = nullptr; } + + if (mState.mAttachedComputeShader) + { + mState.mAttachedComputeShader->release(); + mState.mAttachedComputeShader = nullptr; + } } mState.mAttributes.clear(); @@ -536,6 +714,7 @@ void Program::unlink(bool destroy) mState.mUniformLocations.clear(); mState.mUniformBlocks.clear(); mState.mOutputVariables.clear(); + mState.mComputeShaderLocalSize.fill(1); mValidated = false; @@ -579,6 +758,10 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt return Error(GL_NO_ERROR); } + mState.mComputeShaderLocalSize[0] = stream.readInt<int>(); + mState.mComputeShaderLocalSize[1] = stream.readInt<int>(); + mState.mComputeShaderLocalSize[2] = stream.readInt<int>(); + static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8, "Too many vertex attribs for mask"); mState.mActiveAttribLocationsMask = stream.readInt<unsigned long>(); @@ -700,6 +883,10 @@ Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, G stream.writeInt(ANGLE_MINOR_VERSION); stream.writeBytes(reinterpret_cast<const unsigned char*>(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE); + stream.writeInt(mState.mComputeShaderLocalSize[0]); + stream.writeInt(mState.mComputeShaderLocalSize[1]); + stream.writeInt(mState.mComputeShaderLocalSize[2]); + stream.writeInt(mState.mActiveAttribLocationsMask.to_ulong()); stream.writeInt(mState.mAttributes.size()); @@ -871,6 +1058,15 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade { int total = 0; + if (mState.mAttachedComputeShader) + { + if (total < maxCount) + { + shaders[total] = mState.mAttachedComputeShader->getHandle(); + total++; + } + } + if (mState.mAttachedVertexShader) { if (total < maxCount) @@ -1623,16 +1819,17 @@ GLenum Program::getTransformFeedbackBufferMode() const return mState.mTransformFeedbackBufferMode; } -// static bool Program::linkVaryings(InfoLog &infoLog, const Shader *vertexShader, - const Shader *fragmentShader) + const Shader *fragmentShader) const { ASSERT(vertexShader->getShaderVersion() == fragmentShader->getShaderVersion()); const std::vector<sh::Varying> &vertexVaryings = vertexShader->getVaryings(); const std::vector<sh::Varying> &fragmentVaryings = fragmentShader->getVaryings(); + std::map<GLuint, std::string> staticFragmentInputLocations; + for (const sh::Varying &output : fragmentVaryings) { bool matched = false; @@ -1665,6 +1862,29 @@ bool Program::linkVaryings(InfoLog &infoLog, infoLog << "Fragment varying " << output.name << " does not match any vertex varying"; return false; } + + // Check for aliased path rendering input bindings (if any). + // If more than one binding refer statically to the same + // location the link must fail. + + if (!output.staticUse) + continue; + + const auto inputBinding = mFragmentInputBindings.getBinding(output.name); + if (inputBinding == -1) + continue; + + const auto it = staticFragmentInputLocations.find(inputBinding); + if (it == std::end(staticFragmentInputLocations)) + { + staticFragmentInputLocations.insert(std::make_pair(inputBinding, output.name)); + } + else + { + infoLog << "Binding for fragment input " << output.name << " conflicts with " + << it->second; + return false; + } } // TODO(jmadill): verify no unmatched vertex varyings? @@ -1672,17 +1892,14 @@ bool Program::linkVaryings(InfoLog &infoLog, return true; } -bool Program::linkUniforms(gl::InfoLog &infoLog, - const gl::Caps &caps, - const Bindings &uniformBindings) +bool Program::validateVertexAndFragmentUniforms(InfoLog &infoLog) const { + // Check that uniforms defined in the vertex and fragment shaders are identical + std::map<std::string, LinkedUniform> linkedUniforms; const std::vector<sh::Uniform> &vertexUniforms = mState.mAttachedVertexShader->getUniforms(); const std::vector<sh::Uniform> &fragmentUniforms = mState.mAttachedFragmentShader->getUniforms(); - // Check that uniforms defined in the vertex and fragment shaders are identical - std::map<std::string, LinkedUniform> linkedUniforms; - for (const sh::Uniform &vertexUniform : vertexUniforms) { linkedUniforms[vertexUniform.name] = LinkedUniform(vertexUniform); @@ -1701,6 +1918,21 @@ bool Program::linkUniforms(gl::InfoLog &infoLog, } } } + return true; +} + +bool Program::linkUniforms(gl::InfoLog &infoLog, + const gl::Caps &caps, + const Bindings &uniformBindings) +{ + if (mState.mAttachedVertexShader && mState.mAttachedFragmentShader) + { + ASSERT(mState.mAttachedComputeShader == nullptr); + if (!validateVertexAndFragmentUniforms(infoLog)) + { + return false; + } + } // Flatten the uniforms list (nested fields) into a simple list (no nesting). // Also check the maximum uniform vector and sampler counts. @@ -1810,7 +2042,10 @@ bool Program::indexUniforms(gl::InfoLog &infoLog, return true; } -bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform) +bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, + const std::string &uniformName, + const sh::InterfaceBlockField &vertexUniform, + const sh::InterfaceBlockField &fragmentUniform) { // We don't validate precision on UBO fields. See resolution of Khronos bug 10287. if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, false)) @@ -1934,36 +2169,40 @@ bool Program::linkAttributes(const ContextState &data, return true; } -bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) +bool Program::validateUniformBlocksCount(GLuint maxUniformBlocks, + const std::vector<sh::InterfaceBlock> &intefaceBlocks, + const std::string &errorMessage, + InfoLog &infoLog) const { - const Shader &vertexShader = *mState.mAttachedVertexShader; - const Shader &fragmentShader = *mState.mAttachedFragmentShader; - - const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); - const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); + GLuint blockCount = 0; + for (const sh::InterfaceBlock &block : intefaceBlocks) + { + if (block.staticUse || block.layout != sh::BLOCKLAYOUT_PACKED) + { + if (++blockCount > maxUniformBlocks) + { + infoLog << errorMessage << maxUniformBlocks << ")"; + return false; + } + } + } + return true; +} +bool Program::validateVertexAndFragmentInterfaceBlocks( + const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks, + const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks, + InfoLog &infoLog) const +{ // Check that interface blocks defined in the vertex and fragment shaders are identical - typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap; + typedef std::map<std::string, const sh::InterfaceBlock *> UniformBlockMap; UniformBlockMap linkedUniformBlocks; - GLuint vertexBlockCount = 0; for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks) { linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; - - // Note: shared and std140 layouts are always considered active - if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) - { - if (++vertexBlockCount > caps.maxVertexUniformBlocks) - { - infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (" - << caps.maxVertexUniformBlocks << ")"; - return false; - } - } } - GLuint fragmentBlockCount = 0; for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks) { auto entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); @@ -1975,26 +2214,59 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) return false; } } + } + return true; +} + +bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) +{ + if (mState.mAttachedComputeShader) + { + const Shader &computeShader = *mState.mAttachedComputeShader; + const auto &computeInterfaceBlocks = computeShader.getInterfaceBlocks(); - // Note: shared and std140 layouts are always considered active - if (fragmentInterfaceBlock.staticUse || - fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) + if (!validateUniformBlocksCount( + caps.maxComputeUniformBlocks, computeInterfaceBlocks, + "Compute shader uniform block count exceeds GL_MAX_COMPUTE_UNIFORM_BLOCKS (", + infoLog)) { - if (++fragmentBlockCount > caps.maxFragmentUniformBlocks) - { - infoLog - << "Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (" - << caps.maxFragmentUniformBlocks << ")"; - return false; - } + return false; } + return true; + } + + const Shader &vertexShader = *mState.mAttachedVertexShader; + const Shader &fragmentShader = *mState.mAttachedFragmentShader; + + const auto &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); + const auto &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); + + if (!validateUniformBlocksCount( + caps.maxVertexUniformBlocks, vertexInterfaceBlocks, + "Vertex shader uniform block count exceeds GL_MAX_VERTEX_UNIFORM_BLOCKS (", infoLog)) + { + return false; + } + if (!validateUniformBlocksCount( + caps.maxFragmentUniformBlocks, fragmentInterfaceBlocks, + "Fragment shader uniform block count exceeds GL_MAX_FRAGMENT_UNIFORM_BLOCKS (", + infoLog)) + { + + return false; + } + if (!validateVertexAndFragmentInterfaceBlocks(vertexInterfaceBlocks, fragmentInterfaceBlocks, + infoLog)) + { + return false; } return true; } -bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, - const sh::InterfaceBlock &fragmentInterfaceBlock) +bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, + const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock) const { const char* blockName = vertexInterfaceBlock.name.c_str(); // validate blocks for the same member types @@ -2285,58 +2557,79 @@ void Program::linkOutputVariables() } } -bool Program::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog) +bool Program::flattenUniformsAndCheckCapsForShader(const gl::Shader &shader, + GLuint maxUniformComponents, + GLuint maxTextureImageUnits, + const std::string &componentsErrorMessage, + const std::string &samplerErrorMessage, + std::vector<LinkedUniform> &samplerUniforms, + InfoLog &infoLog) { - const gl::Shader *vertexShader = mState.getAttachedVertexShader(); - VectorAndSamplerCount vsCounts; - - std::vector<LinkedUniform> samplerUniforms; - - for (const sh::Uniform &uniform : vertexShader->getUniforms()) + VectorAndSamplerCount vasCount; + for (const sh::Uniform &uniform : shader.getUniforms()) { if (uniform.staticUse) { - vsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms); + vasCount += flattenUniform(uniform, uniform.name, &samplerUniforms); } } - if (vsCounts.vectorCount > caps.maxVertexUniformVectors) + if (vasCount.vectorCount > maxUniformComponents) { - infoLog << "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (" - << caps.maxVertexUniformVectors << ")."; + infoLog << componentsErrorMessage << maxUniformComponents << ")."; return false; } - if (vsCounts.samplerCount > caps.maxVertexTextureImageUnits) + if (vasCount.samplerCount > maxTextureImageUnits) { - infoLog << "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (" - << caps.maxVertexTextureImageUnits << ")."; + infoLog << samplerErrorMessage << maxTextureImageUnits << ")."; return false; } - const gl::Shader *fragmentShader = mState.getAttachedFragmentShader(); - VectorAndSamplerCount fsCounts; + return true; +} + +bool Program::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog) +{ + std::vector<LinkedUniform> samplerUniforms; - for (const sh::Uniform &uniform : fragmentShader->getUniforms()) + if (mState.mAttachedComputeShader) { - if (uniform.staticUse) + const gl::Shader *computeShader = mState.getAttachedComputeShader(); + + // TODO (mradev): check whether we need finer-grained component counting + if (!flattenUniformsAndCheckCapsForShader( + *computeShader, caps.maxComputeUniformComponents / 4, + caps.maxComputeTextureImageUnits, + "Compute shader active uniforms exceed MAX_COMPUTE_UNIFORM_COMPONENTS (", + "Compute shader sampler count exceeds MAX_COMPUTE_TEXTURE_IMAGE_UNITS (", + samplerUniforms, infoLog)) { - fsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms); + return false; } } - - if (fsCounts.vectorCount > caps.maxFragmentUniformVectors) + else { - infoLog << "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (" - << caps.maxFragmentUniformVectors << ")."; - return false; - } + const gl::Shader *vertexShader = mState.getAttachedVertexShader(); - if (fsCounts.samplerCount > caps.maxTextureImageUnits) - { - infoLog << "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (" - << caps.maxTextureImageUnits << ")."; - return false; + if (!flattenUniformsAndCheckCapsForShader( + *vertexShader, caps.maxVertexUniformVectors, caps.maxVertexTextureImageUnits, + "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (", + "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (", + samplerUniforms, infoLog)) + { + return false; + } + const gl::Shader *fragmentShader = mState.getAttachedFragmentShader(); + + if (!flattenUniformsAndCheckCapsForShader( + *fragmentShader, caps.maxFragmentUniformVectors, caps.maxTextureImageUnits, + "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (", + "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (", samplerUniforms, + infoLog)) + { + return false; + } } mSamplerUniformRange.start = static_cast<unsigned int>(mState.mUniforms.size()); @@ -2406,14 +2699,39 @@ Program::VectorAndSamplerCount Program::flattenUniform(const sh::ShaderVariable void Program::gatherInterfaceBlockInfo() { + ASSERT(mState.mUniformBlocks.empty()); + + if (mState.mAttachedComputeShader) + { + const gl::Shader *computeShader = mState.getAttachedComputeShader(); + + for (const sh::InterfaceBlock &computeBlock : computeShader->getInterfaceBlocks()) + { + + // Only 'packed' blocks are allowed to be considered inactive. + if (!computeBlock.staticUse && computeBlock.layout == sh::BLOCKLAYOUT_PACKED) + continue; + + for (gl::UniformBlock &block : mState.mUniformBlocks) + { + if (block.name == computeBlock.name) + { + block.computeStaticUse = computeBlock.staticUse; + } + } + + defineUniformBlock(computeBlock, GL_COMPUTE_SHADER); + } + return; + } + std::set<std::string> visitedList; const gl::Shader *vertexShader = mState.getAttachedVertexShader(); - ASSERT(mState.mUniformBlocks.empty()); for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks()) { - // Only 'packed' blocks are allowed to be considered inacive. + // Only 'packed' blocks are allowed to be considered inactive. if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED) continue; @@ -2428,7 +2746,7 @@ void Program::gatherInterfaceBlockInfo() for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks()) { - // Only 'packed' blocks are allowed to be considered inacive. + // Only 'packed' blocks are allowed to be considered inactive. if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED) continue; @@ -2518,14 +2836,25 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu UniformBlock block(interfaceBlock.name, true, arrayElement); block.memberUniformIndexes = blockUniformIndexes; - if (shaderType == GL_VERTEX_SHADER) + switch (shaderType) { - block.vertexStaticUse = interfaceBlock.staticUse; - } - else - { - ASSERT(shaderType == GL_FRAGMENT_SHADER); - block.fragmentStaticUse = interfaceBlock.staticUse; + case GL_VERTEX_SHADER: + { + block.vertexStaticUse = interfaceBlock.staticUse; + break; + } + case GL_FRAGMENT_SHADER: + { + block.fragmentStaticUse = interfaceBlock.staticUse; + break; + } + case GL_COMPUTE_SHADER: + { + block.computeStaticUse = interfaceBlock.staticUse; + break; + } + default: + UNREACHABLE(); } // TODO(jmadill): Determine if we can ever have an inactive array element block. @@ -2545,14 +2874,25 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu UniformBlock block(interfaceBlock.name, false, 0); block.memberUniformIndexes = blockUniformIndexes; - if (shaderType == GL_VERTEX_SHADER) + switch (shaderType) { - block.vertexStaticUse = interfaceBlock.staticUse; - } - else - { - ASSERT(shaderType == GL_FRAGMENT_SHADER); - block.fragmentStaticUse = interfaceBlock.staticUse; + case GL_VERTEX_SHADER: + { + block.vertexStaticUse = interfaceBlock.staticUse; + break; + } + case GL_FRAGMENT_SHADER: + { + block.fragmentStaticUse = interfaceBlock.staticUse; + break; + } + case GL_COMPUTE_SHADER: + { + block.computeStaticUse = interfaceBlock.staticUse; + break; + } + default: + UNREACHABLE(); } block.dataSize = static_cast<unsigned int>(blockSize); diff --git a/chromium/third_party/angle/src/libANGLE/Program.h b/chromium/third_party/angle/src/libANGLE/Program.h index 10cdec1af99..03212a5cdd7 100644 --- a/chromium/third_party/angle/src/libANGLE/Program.h +++ b/chromium/third_party/angle/src/libANGLE/Program.h @@ -137,6 +137,24 @@ struct VariableLocation bool ignored; }; +// Information about a variable binding. +// Currently used by CHROMIUM_path_rendering +struct BindingInfo +{ + // The type of binding, for example GL_FLOAT_VEC3. + // This can be GL_NONE if the variable is optimized away. + GLenum type; + + // This is the name of the variable in + // the translated shader program. Note that + // this can be empty in the case where the + // variable has been optimized away. + std::string name; + + // True if the binding is valid, otherwise false. + bool valid; +}; + class ProgramState final : angle::NonCopyable { public: @@ -147,6 +165,7 @@ class ProgramState final : angle::NonCopyable const Shader *getAttachedVertexShader() const { return mAttachedVertexShader; } const Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; } + const Shader *getAttachedComputeShader() const { return mAttachedComputeShader; } const std::vector<std::string> &getTransformFeedbackVaryingNames() const { return mTransformFeedbackVaryingNames; @@ -180,8 +199,11 @@ class ProgramState final : angle::NonCopyable std::string mLabel; + sh::WorkGroupSize mComputeShaderLocalSize; + Shader *mAttachedFragmentShader; Shader *mAttachedVertexShader; + Shader *mAttachedComputeShader; std::vector<std::string> mTransformFeedbackVaryingNames; std::vector<sh::Varying> mTransformFeedbackVaryingVars; @@ -229,6 +251,14 @@ class Program final : angle::NonCopyable, public LabeledObject void bindAttributeLocation(GLuint index, const char *name); void bindUniformLocation(GLuint index, const char *name); + // CHROMIUM_path_rendering + BindingInfo getFragmentInputBindingInfo(GLint index) const; + void bindFragmentInputLocation(GLint index, const char *name); + void pathFragmentInputGen(GLint index, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + Error link(const ContextState &data); bool isLinked() const; @@ -351,14 +381,22 @@ class Program final : angle::NonCopyable, public LabeledObject InfoLog &infoLog, const Bindings &attributeBindings, const Shader *vertexShader); + bool validateUniformBlocksCount(GLuint maxUniformBlocks, + const std::vector<sh::InterfaceBlock> &block, + const std::string &errorMessage, + InfoLog &infoLog) const; + bool validateVertexAndFragmentInterfaceBlocks( + const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks, + const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks, + InfoLog &infoLog) const; bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps); - static bool linkVaryings(InfoLog &infoLog, - const Shader *vertexShader, - const Shader *fragmentShader); + bool linkVaryings(InfoLog &infoLog, const Shader *vertexShader, const Shader *fragmentShader) const; + bool validateVertexAndFragmentUniforms(InfoLog &infoLog) const; bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps, const Bindings &uniformBindings); bool indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps, const Bindings &uniformBindings); - bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, - const sh::InterfaceBlock &fragmentInterfaceBlock); + bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, + const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock) const; static bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, @@ -382,6 +420,13 @@ class Program final : angle::NonCopyable, public LabeledObject std::vector<const sh::Varying *> getMergedVaryings() const; void linkOutputVariables(); + bool flattenUniformsAndCheckCapsForShader(const gl::Shader &shader, + GLuint maxUniformComponents, + GLuint maxTextureImageUnits, + const std::string &componentsErrorMessage, + const std::string &samplerErrorMessage, + std::vector<LinkedUniform> &samplerUniforms, + InfoLog &infoLog); bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog); struct VectorAndSamplerCount @@ -430,6 +475,9 @@ class Program final : angle::NonCopyable, public LabeledObject Bindings mAttributeBindings; Bindings mUniformBindings; + // CHROMIUM_path_rendering + Bindings mFragmentInputBindings; + bool mLinked; bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use diff --git a/chromium/third_party/angle/src/libANGLE/Renderbuffer.cpp b/chromium/third_party/angle/src/libANGLE/Renderbuffer.cpp index 13033a0885a..977117d24aa 100644 --- a/chromium/third_party/angle/src/libANGLE/Renderbuffer.cpp +++ b/chromium/third_party/angle/src/libANGLE/Renderbuffer.cpp @@ -25,7 +25,7 @@ Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id) mLabel(), mWidth(0), mHeight(0), - mInternalFormat(GL_RGBA4), + mFormat(GL_RGBA4), mSamples(0) { } @@ -53,7 +53,7 @@ Error Renderbuffer::setStorage(GLenum internalformat, size_t width, size_t heigh mWidth = static_cast<GLsizei>(width); mHeight = static_cast<GLsizei>(height); - mInternalFormat = internalformat; + mFormat = Format(internalformat); mSamples = 0; mDirtyChannel.signal(); @@ -69,7 +69,7 @@ Error Renderbuffer::setStorageMultisample(size_t samples, GLenum internalformat, mWidth = static_cast<GLsizei>(width); mHeight = static_cast<GLsizei>(height); - mInternalFormat = internalformat; + mFormat = Format(internalformat); mSamples = static_cast<GLsizei>(samples); mDirtyChannel.signal(); @@ -87,7 +87,7 @@ Error Renderbuffer::setStorageEGLImageTarget(egl::Image *image) mWidth = static_cast<GLsizei>(image->getWidth()); mHeight = static_cast<GLsizei>(image->getHeight()); - mInternalFormat = image->getInternalFormat(); + mFormat = Format(image->getFormat()); mSamples = 0; mDirtyChannel.signal(); @@ -116,9 +116,9 @@ GLsizei Renderbuffer::getHeight() const return mHeight; } -GLenum Renderbuffer::getInternalFormat() const +const Format &Renderbuffer::getFormat() const { - return mInternalFormat; + return mFormat; } GLsizei Renderbuffer::getSamples() const @@ -128,32 +128,32 @@ GLsizei Renderbuffer::getSamples() const GLuint Renderbuffer::getRedSize() const { - return GetInternalFormatInfo(mInternalFormat).redBits; + return mFormat.info->redBits; } GLuint Renderbuffer::getGreenSize() const { - return GetInternalFormatInfo(mInternalFormat).greenBits; + return mFormat.info->greenBits; } GLuint Renderbuffer::getBlueSize() const { - return GetInternalFormatInfo(mInternalFormat).blueBits; + return mFormat.info->blueBits; } GLuint Renderbuffer::getAlphaSize() const { - return GetInternalFormatInfo(mInternalFormat).alphaBits; + return mFormat.info->alphaBits; } GLuint Renderbuffer::getDepthSize() const { - return GetInternalFormatInfo(mInternalFormat).depthBits; + return mFormat.info->depthBits; } GLuint Renderbuffer::getStencilSize() const { - return GetInternalFormatInfo(mInternalFormat).stencilBits; + return mFormat.info->stencilBits; } void Renderbuffer::onAttach() diff --git a/chromium/third_party/angle/src/libANGLE/Renderbuffer.h b/chromium/third_party/angle/src/libANGLE/Renderbuffer.h index 04af03e879d..eceda70bcf7 100644 --- a/chromium/third_party/angle/src/libANGLE/Renderbuffer.h +++ b/chromium/third_party/angle/src/libANGLE/Renderbuffer.h @@ -17,6 +17,7 @@ #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Image.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/RenderbufferImpl.h" namespace gl @@ -46,7 +47,7 @@ class Renderbuffer final : public egl::ImageSibling, GLsizei getWidth() const; GLsizei getHeight() const; - GLenum getInternalFormat() const; + const Format &getFormat() const; GLsizei getSamples() const; GLuint getRedSize() const; GLuint getGreenSize() const; @@ -57,7 +58,11 @@ class Renderbuffer final : public egl::ImageSibling, // FramebufferAttachmentObject Impl Extents getAttachmentSize(const FramebufferAttachment::Target &target) const override; - GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &/*target*/) const override { return getInternalFormat(); } + const Format &getAttachmentFormat( + const FramebufferAttachment::Target & /*target*/) const override + { + return getFormat(); + } GLsizei getAttachmentSamples(const FramebufferAttachment::Target &/*target*/) const override { return getSamples(); } void onAttach() override; @@ -73,7 +78,7 @@ class Renderbuffer final : public egl::ImageSibling, GLsizei mWidth; GLsizei mHeight; - GLenum mInternalFormat; + Format mFormat; GLsizei mSamples; }; diff --git a/chromium/third_party/angle/src/libANGLE/ResourceManager.cpp b/chromium/third_party/angle/src/libANGLE/ResourceManager.cpp index 7f963874a09..713c1046d9c 100644 --- a/chromium/third_party/angle/src/libANGLE/ResourceManager.cpp +++ b/chromium/third_party/angle/src/libANGLE/ResourceManager.cpp @@ -97,13 +97,10 @@ GLuint ResourceManager::createShader(rx::GLImplFactory *factory, const gl::Limitations &rendererLimitations, GLenum type) { + ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER); GLuint handle = mProgramShaderHandleAllocator.allocate(); - if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER) - { - mShaderMap[handle] = new Shader(this, factory, rendererLimitations, type, handle); - } - else UNREACHABLE(); + mShaderMap[handle] = new Shader(this, factory, rendererLimitations, type, handle); return handle; } @@ -547,4 +544,19 @@ bool ResourceManager::isSampler(GLuint sampler) return mSamplerMap.find(sampler) != mSamplerMap.end(); } +bool ResourceManager::isTextureGenerated(GLuint texture) const +{ + return texture == 0 || mTextureMap.find(texture) != mTextureMap.end(); +} + +bool ResourceManager::isBufferGenerated(GLuint buffer) const +{ + return buffer == 0 || mBufferMap.find(buffer) != mBufferMap.end(); +} + +bool ResourceManager::isRenderbufferGenerated(GLuint renderbuffer) const +{ + return renderbuffer == 0 || mRenderbufferMap.find(renderbuffer) != mRenderbufferMap.end(); +} + } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/ResourceManager.h b/chromium/third_party/angle/src/libANGLE/ResourceManager.h index a673257e157..03df64556f5 100644 --- a/chromium/third_party/angle/src/libANGLE/ResourceManager.h +++ b/chromium/third_party/angle/src/libANGLE/ResourceManager.h @@ -85,6 +85,11 @@ class ResourceManager : angle::NonCopyable bool isSampler(GLuint sampler); + // GL_CHROMIUM_bind_generates_resource + bool isTextureGenerated(GLuint texture) const; + bool isBufferGenerated(GLuint buffer) const; + bool isRenderbufferGenerated(GLuint renderbuffer) const; + private: void createTextureInternal(GLuint handle); diff --git a/chromium/third_party/angle/src/libANGLE/Shader.cpp b/chromium/third_party/angle/src/libANGLE/Shader.cpp index bf0f742cb18..e008772d753 100644 --- a/chromium/third_party/angle/src/libANGLE/Shader.cpp +++ b/chromium/third_party/angle/src/libANGLE/Shader.cpp @@ -75,6 +75,7 @@ bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) ShaderState::ShaderState(GLenum shaderType) : mLabel(), mShaderType(shaderType), mShaderVersion(100) { + mLocalSize.fill(-1); } ShaderState::~ShaderState() @@ -242,9 +243,9 @@ void Shader::compile(Compiler *compiler) std::stringstream sourceStream; std::string sourcePath; - int additionalOptions = + ShCompileOptions additionalOptions = mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); - int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); + ShCompileOptions compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes // in fragment shaders. Shader compilation will fail. To provide a better error message we can @@ -306,18 +307,28 @@ void Shader::compile(Compiler *compiler) mState.mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); mState.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); - if (mState.mShaderType == GL_VERTEX_SHADER) + switch (mState.mShaderType) { - mState.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle)); - } - else - { - ASSERT(mState.mShaderType == GL_FRAGMENT_SHADER); - - // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. - std::sort(mState.mVaryings.begin(), mState.mVaryings.end(), CompareShaderVar); - mState.mActiveOutputVariables = - GetActiveShaderVariables(ShGetOutputVariables(compilerHandle)); + case GL_COMPUTE_SHADER: + { + mState.mLocalSize = ShGetComputeShaderLocalGroupSize(compilerHandle); + break; + } + case GL_VERTEX_SHADER: + { + mState.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle)); + break; + } + case GL_FRAGMENT_SHADER: + { + // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. + std::sort(mState.mVaryings.begin(), mState.mVaryings.end(), CompareShaderVar); + mState.mActiveOutputVariables = + GetActiveShaderVariables(ShGetOutputVariables(compilerHandle)); + break; + } + default: + UNREACHABLE(); } ASSERT(!mState.mTranslatedSource.empty()); diff --git a/chromium/third_party/angle/src/libANGLE/Shader.h b/chromium/third_party/angle/src/libANGLE/Shader.h index 237a91544ed..d73400a80c9 100644 --- a/chromium/third_party/angle/src/libANGLE/Shader.h +++ b/chromium/third_party/angle/src/libANGLE/Shader.h @@ -70,6 +70,8 @@ class ShaderState final : angle::NonCopyable std::string mTranslatedSource; std::string mSource; + sh::WorkGroupSize mLocalSize; + std::vector<sh::Varying> mVaryings; std::vector<sh::Uniform> mUniforms; std::vector<sh::InterfaceBlock> mInterfaceBlocks; @@ -127,6 +129,8 @@ class Shader final : angle::NonCopyable, public LabeledObject int getSemanticIndex(const std::string &attributeName) const; + const sh::WorkGroupSize &getWorkGroupSize() const { return mState.mLocalSize; } + private: static void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer); diff --git a/chromium/third_party/angle/src/libANGLE/State.cpp b/chromium/third_party/angle/src/libANGLE/State.cpp index a5ae996144c..f7d48509f3d 100644 --- a/chromium/third_party/angle/src/libANGLE/State.cpp +++ b/chromium/third_party/angle/src/libANGLE/State.cpp @@ -23,6 +23,16 @@ #include "libANGLE/VertexArray.h" #include "libANGLE/formatutils.h" +namespace +{ + +GLenum ActiveQueryType(const GLenum type) +{ + return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type; +} + +} // anonymous namepace + namespace gl { @@ -40,6 +50,7 @@ State::State() mLineWidth(0), mGenerateMipmapHint(GL_NONE), mFragmentShaderDerivativeHint(GL_NONE), + mBindGeneratesResource(true), mNearZ(0), mFarZ(0), mReadFramebuffer(nullptr), @@ -61,7 +72,8 @@ State::~State() void State::initialize(const Caps &caps, const Extensions &extensions, GLuint clientVersion, - bool debug) + bool debug, + bool bindGeneratesResource) { mMaxDrawBuffers = caps.maxDrawBuffers; mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; @@ -127,6 +139,8 @@ void State::initialize(const Caps &caps, mGenerateMipmapHint = GL_DONT_CARE; mFragmentShaderDerivativeHint = GL_DONT_CARE; + mBindGeneratesResource = bindGeneratesResource; + mLineWidth = 1.0f; mViewport.x = 0; @@ -648,6 +662,8 @@ bool State::getEnableFeature(GLenum feature) const return mDebug.isOutputSynchronous(); case GL_DEBUG_OUTPUT: return mDebug.isOutputEnabled(); + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + return isBindGeneratesResourceEnabled(); default: UNREACHABLE(); return false; } } @@ -678,6 +694,11 @@ void State::setFragmentShaderDerivativeHint(GLenum hint) // Ignore for now. It is valid for implementations to ignore hint. } +bool State::isBindGeneratesResourceEnabled() const +{ + return mBindGeneratesResource; +} + void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) { mViewport.x = x; @@ -1026,12 +1047,12 @@ bool State::removeTransformFeedbackBinding(GLuint transformFeedback) return false; } -bool State::isQueryActive(GLenum type) const +bool State::isQueryActive(const GLenum type) const { for (auto &iter : mActiveQueries) { - Query *query = iter.second.get(); - if (query != nullptr && query->getType() == type) + const Query *query = iter.second.get(); + if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type)) { return true; } @@ -1476,6 +1497,9 @@ void State::getBooleanv(GLenum pname, GLboolean *params) case GL_SAMPLE_ALPHA_TO_ONE_EXT: *params = mSampleAlphaToOne; break; + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE; + break; default: UNREACHABLE(); break; @@ -1720,6 +1744,11 @@ void State::getIntegerv(const ContextState &data, GLenum pname, GLint *params) *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY); break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), + GL_TEXTURE_EXTERNAL_OES); + break; case GL_UNIFORM_BUFFER_BINDING: *params = mGenericUniformBuffer.id(); break; @@ -1787,7 +1816,7 @@ void State::getPointerv(GLenum pname, void **params) const } } -bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) +void State::getIntegeri_v(GLenum target, GLuint index, GLint *data) { switch (target) { @@ -1804,13 +1833,12 @@ bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) } break; default: - return false; + UNREACHABLE(); + break; } - - return true; } -bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) +void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) { switch (target) { @@ -1839,10 +1867,14 @@ bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) } break; default: - return false; + UNREACHABLE(); + break; } +} - return true; +void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) +{ + UNREACHABLE(); } bool State::hasMappedBuffer(GLenum target) const diff --git a/chromium/third_party/angle/src/libANGLE/State.h b/chromium/third_party/angle/src/libANGLE/State.h index 5089139ffc2..5efff181bf5 100644 --- a/chromium/third_party/angle/src/libANGLE/State.h +++ b/chromium/third_party/angle/src/libANGLE/State.h @@ -13,6 +13,7 @@ #include <memory> #include "common/angleutils.h" +#include "common/Color.h" #include "libANGLE/Debug.h" #include "libANGLE/Program.h" #include "libANGLE/RefCountObject.h" @@ -41,7 +42,8 @@ class State : angle::NonCopyable void initialize(const Caps &caps, const Extensions &extensions, GLuint clientVersion, - bool debug); + bool debug, + bool bindGeneratesResource); void reset(); // State chunk getters @@ -146,6 +148,9 @@ class State : angle::NonCopyable void setGenerateMipmapHint(GLenum hint); void setFragmentShaderDerivativeHint(GLenum hint); + // GL_CHROMIUM_bind_generates_resource + bool isBindGeneratesResourceEnabled() const; + // Viewport state setter/getter void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height); const Rectangle &getViewport() const; @@ -198,7 +203,7 @@ class State : angle::NonCopyable bool removeTransformFeedbackBinding(GLuint transformFeedback); // Query binding manipulation - bool isQueryActive(GLenum type) const; + bool isQueryActive(const GLenum type) const; bool isQueryActive(Query *query) const; void setActiveQuery(GLenum target, Query *query); GLuint getActiveQueryId(GLenum target) const; @@ -290,8 +295,9 @@ class State : angle::NonCopyable void getFloatv(GLenum pname, GLfloat *params); void getIntegerv(const ContextState &data, GLenum pname, GLint *params); void getPointerv(GLenum pname, void **params) const; - bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); - bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); + void getIntegeri_v(GLenum target, GLuint index, GLint *data); + void getInteger64i_v(GLenum target, GLuint index, GLint64 *data); + void getBooleani_v(GLenum target, GLuint index, GLboolean *data); bool hasMappedBuffer(GLenum target) const; @@ -416,6 +422,8 @@ class State : angle::NonCopyable GLenum mGenerateMipmapHint; GLenum mFragmentShaderDerivativeHint; + bool mBindGeneratesResource; + Rectangle mViewport; float mNearZ; float mFarZ; @@ -478,4 +486,3 @@ class State : angle::NonCopyable } // namespace gl #endif // LIBANGLE_STATE_H_ - diff --git a/chromium/third_party/angle/src/libANGLE/Surface.cpp b/chromium/third_party/angle/src/libANGLE/Surface.cpp index fb3c6075148..6028b7f671c 100644 --- a/chromium/third_party/angle/src/libANGLE/Surface.cpp +++ b/chromium/third_party/angle/src/libANGLE/Surface.cpp @@ -17,6 +17,7 @@ #include "libANGLE/Config.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/EGLImplFactory.h" namespace egl @@ -44,7 +45,9 @@ Surface::Surface(EGLint surfaceType, const egl::Config *config, const AttributeM mRenderBuffer(EGL_BACK_BUFFER), mSwapBehavior(EGL_NONE), mOrientation(0), - mTexture() + mTexture(), + mBackFormat(config->renderTargetFormat), + mDSFormat(config->depthStencilFormat) { mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE); mFlexibleSurfaceCompatibilityRequested = @@ -229,10 +232,10 @@ gl::Extents Surface::getAttachmentSize(const gl::FramebufferAttachment::Target & return gl::Extents(getWidth(), getHeight(), 1); } -GLenum Surface::getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const +const gl::Format &Surface::getAttachmentFormat( + const gl::FramebufferAttachment::Target &target) const { - const egl::Config *config = getConfig(); - return (target.binding() == GL_BACK ? config->renderTargetFormat : config->depthStencilFormat); + return (target.binding() == GL_BACK ? mBackFormat : mDSFormat); } GLsizei Surface::getAttachmentSamples(const gl::FramebufferAttachment::Target &target) const diff --git a/chromium/third_party/angle/src/libANGLE/Surface.h b/chromium/third_party/angle/src/libANGLE/Surface.h index 10a4044e0ac..4e60771afdf 100644 --- a/chromium/third_party/angle/src/libANGLE/Surface.h +++ b/chromium/third_party/angle/src/libANGLE/Surface.h @@ -17,6 +17,7 @@ #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/SurfaceImpl.h" namespace gl @@ -83,7 +84,8 @@ class Surface : public gl::FramebufferAttachmentObject // FramebufferAttachmentObject implementation gl::Extents getAttachmentSize(const gl::FramebufferAttachment::Target &target) const override; - GLenum getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const override; + const gl::Format &getAttachmentFormat( + const gl::FramebufferAttachment::Target &target) const override; GLsizei getAttachmentSamples(const gl::FramebufferAttachment::Target &target) const override; void onAttach() override {} @@ -136,6 +138,9 @@ class Surface : public gl::FramebufferAttachmentObject EGLint mOrientation; BindingPointer<gl::Texture> mTexture; + + gl::Format mBackFormat; + gl::Format mDSFormat; }; class WindowSurface final : public Surface diff --git a/chromium/third_party/angle/src/libANGLE/Texture.cpp b/chromium/third_party/angle/src/libANGLE/Texture.cpp index a93f423f119..4405fe9ab10 100644 --- a/chromium/third_party/angle/src/libANGLE/Texture.cpp +++ b/chromium/third_party/angle/src/libANGLE/Texture.cpp @@ -186,7 +186,7 @@ bool TextureState::isCubeComplete() const const ImageDesc &faceImageDesc = getImageDesc(face, 0); if (faceImageDesc.size.width != baseImageDesc.size.width || faceImageDesc.size.height != baseImageDesc.size.height || - faceImageDesc.internalFormat != baseImageDesc.internalFormat) + !Format::SameSized(faceImageDesc.format, baseImageDesc.format)) { return false; } @@ -199,16 +199,16 @@ bool TextureState::isSamplerComplete(const SamplerState &samplerState, const ContextState &data) const { const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); - const TextureCaps &textureCaps = data.getTextureCap(baseImageDesc.internalFormat); + const TextureCaps &textureCaps = data.getTextureCap(baseImageDesc.format.asSized()); if (!mCompletenessCache.cacheValid || mCompletenessCache.samplerState != samplerState || mCompletenessCache.filterable != textureCaps.filterable || - mCompletenessCache.clientVersion != data.getClientVersion() || + mCompletenessCache.clientVersion != data.getClientMajorVersion() || mCompletenessCache.supportsNPOT != data.getExtensions().textureNPOT) { mCompletenessCache.cacheValid = true; mCompletenessCache.samplerState = samplerState; mCompletenessCache.filterable = textureCaps.filterable; - mCompletenessCache.clientVersion = data.getClientVersion(); + mCompletenessCache.clientVersion = data.getClientMajorVersion(); mCompletenessCache.supportsNPOT = data.getExtensions().textureNPOT; mCompletenessCache.samplerComplete = computeSamplerCompleteness(samplerState, data); } @@ -237,13 +237,12 @@ bool TextureState::computeSamplerCompleteness(const SamplerState &samplerState, return false; } - const TextureCaps &textureCaps = data.getTextureCap(baseImageDesc.internalFormat); + const TextureCaps &textureCaps = data.getTextureCap(baseImageDesc.format.asSized()); if (!textureCaps.filterable && !IsPointSampled(samplerState)) { return false; } - - bool npotSupport = data.getExtensions().textureNPOT || data.getClientVersion() >= 3; + bool npotSupport = data.getExtensions().textureNPOT || data.getClientMajorVersion() >= 3; if (!npotSupport) { if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(baseImageDesc.size.width)) || @@ -302,10 +301,13 @@ bool TextureState::computeSamplerCompleteness(const SamplerState &samplerState, // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_- // MODE is NONE, and either the magnification filter is not NEAREST or the mini- // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST. - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(baseImageDesc.internalFormat); - if (formatInfo.depthBits > 0 && data.getClientVersion() > 2) + if (baseImageDesc.format.info->depthBits > 0 && data.getClientMajorVersion() >= 3) { - if (samplerState.compareMode == GL_NONE) + // Note: we restrict this validation to sized types. For the OES_depth_textures + // extension, due to some underspecification problems, we must allow linear filtering + // for legacy compatibility with WebGL 1. + // See http://crbug.com/649200 + if (samplerState.compareMode == GL_NONE && baseImageDesc.format.sized) { if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) || @@ -370,7 +372,7 @@ bool TextureState::computeLevelCompleteness(GLenum target, size_t level) const return false; } - if (levelImageDesc.internalFormat != baseImageDesc.internalFormat) + if (!Format::SameSized(levelImageDesc.format, baseImageDesc.format)) { return false; } @@ -410,12 +412,11 @@ GLenum TextureState::getBaseImageTarget() const return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget; } -ImageDesc::ImageDesc() : ImageDesc(Extents(0, 0, 0), GL_NONE) +ImageDesc::ImageDesc() : ImageDesc(Extents(0, 0, 0), Format::Invalid()) { } -ImageDesc::ImageDesc(const Extents &size, GLenum internalFormat) - : size(size), internalFormat(internalFormat) +ImageDesc::ImageDesc(const Extents &size, const Format &format) : size(size), format(format) { } @@ -437,7 +438,7 @@ void TextureState::setImageDesc(GLenum target, size_t level, const ImageDesc &de void TextureState::setImageDescChain(GLuint baseLevel, GLuint maxLevel, Extents baseSize, - GLenum sizedInternalFormat) + const Format &format) { for (GLuint level = baseLevel; level <= maxLevel; level++) { @@ -447,7 +448,7 @@ void TextureState::setImageDescChain(GLuint baseLevel, (mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth : std::max<int>(baseSize.depth >> relativeLevel, 1)); - ImageDesc levelInfo(levelSize, sizedInternalFormat); + ImageDesc levelInfo(levelSize, format); if (mTarget == GL_TEXTURE_CUBE_MAP) { @@ -741,11 +742,11 @@ size_t Texture::getDepth(GLenum target, size_t level) const return mState.getImageDesc(target, level).size.depth; } -GLenum Texture::getInternalFormat(GLenum target, size_t level) const +const Format &Texture::getFormat(GLenum target, size_t level) const { ASSERT(target == mState.mTarget || (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - return mState.getImageDesc(target, level).internalFormat; + return mState.getImageDesc(target, level).format; } bool Texture::isMipmapComplete() const @@ -782,8 +783,7 @@ Error Texture::setImage(const PixelUnpackState &unpackState, ANGLE_TRY( mTexture->setImage(target, level, internalFormat, size, format, type, unpackState, pixels)); - mState.setImageDesc(target, level, - ImageDesc(size, GetSizedInternalFormat(internalFormat, type))); + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, format, type))); mDirtyChannel.signal(); return NoError(); @@ -820,8 +820,7 @@ Error Texture::setCompressedImage(const PixelUnpackState &unpackState, ANGLE_TRY(mTexture->setCompressedImage(target, level, internalFormat, size, unpackState, imageSize, pixels)); - mState.setImageDesc(target, level, - ImageDesc(size, GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE))); + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat))); mDirtyChannel.signal(); return NoError(); @@ -854,9 +853,9 @@ Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceAre ANGLE_TRY(mTexture->copyImage(target, level, sourceArea, internalFormat, source)); - mState.setImageDesc(target, level, - ImageDesc(Extents(sourceArea.width, sourceArea.height, 1), - GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE))); + const GLenum sizedFormat = GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE); + mState.setImageDesc(target, level, ImageDesc(Extents(sourceArea.width, sourceArea.height, 1), + Format(sizedFormat))); mDirtyChannel.signal(); return NoError(); @@ -871,6 +870,39 @@ Error Texture::copySubImage(GLenum target, size_t level, const Offset &destOffse return mTexture->copySubImage(target, level, destOffset, sourceArea, source); } +Error Texture::copyTexture(GLenum internalFormat, + GLenum type, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Texture *source) +{ + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + releaseTexImageInternal(); + orphanImages(); + + ANGLE_TRY(mTexture->copyTexture(internalFormat, type, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha, source)); + + const auto &sourceDesc = source->mState.getImageDesc(source->getTarget(), 0); + const GLenum sizedFormat = GetSizedInternalFormat(internalFormat, type); + mState.setImageDesc(getTarget(), 0, ImageDesc(sourceDesc.size, Format(sizedFormat))); + mDirtyChannel.signal(); + + return NoError(); +} + +Error Texture::copySubTexture(const Offset &destOffset, + const Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Texture *source) +{ + return mTexture->copySubTexture(destOffset, sourceArea, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha, source); +} + Error Texture::setStorage(GLenum target, GLsizei levels, GLenum internalFormat, const Extents &size) { ASSERT(target == mState.mTarget); @@ -884,7 +916,7 @@ Error Texture::setStorage(GLenum target, GLsizei levels, GLenum internalFormat, mState.mImmutableFormat = true; mState.mImmutableLevels = static_cast<GLuint>(levels); mState.clearImageDescs(); - mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, internalFormat); + mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, Format(internalFormat)); mDirtyChannel.signal(); return NoError(); @@ -911,8 +943,7 @@ Error Texture::generateMipmap() const ImageDesc &baseImageInfo = mState.getImageDesc(mState.getBaseImageTarget(), baseLevel); - mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, - baseImageInfo.internalFormat); + mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format); } mDirtyChannel.signal(); @@ -935,7 +966,7 @@ void Texture::bindTexImageFromSurface(egl::Surface *surface) // Set the image info to the size and format of the surface ASSERT(mState.mTarget == GL_TEXTURE_2D); Extents size(surface->getWidth(), surface->getHeight(), 1); - ImageDesc desc(size, surface->getConfig()->renderTargetFormat); + ImageDesc desc(size, Format(surface->getConfig()->renderTargetFormat)); mState.setImageDesc(mState.mTarget, 0, desc); mDirtyChannel.signal(); } @@ -976,7 +1007,7 @@ void Texture::acquireImageFromStream(const egl::Stream::GLTextureDescription &de mTexture->setImageExternal(mState.mTarget, mBoundStream, desc); Extents size(desc.width, desc.height, 1); - mState.setImageDesc(mState.mTarget, 0, ImageDesc(size, desc.internalFormat)); + mState.setImageDesc(mState.mTarget, 0, ImageDesc(size, Format(desc.internalFormat))); mDirtyChannel.signal(); } @@ -1017,11 +1048,9 @@ Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget) Extents size(static_cast<int>(imageTarget->getWidth()), static_cast<int>(imageTarget->getHeight()), 1); - GLenum internalFormat = imageTarget->getInternalFormat(); - GLenum type = GetInternalFormatInfo(internalFormat).type; mState.clearImageDescs(); - mState.setImageDesc(target, 0, ImageDesc(size, GetSizedInternalFormat(internalFormat, type))); + mState.setImageDesc(target, 0, ImageDesc(size, imageTarget->getFormat())); mDirtyChannel.signal(); return NoError(); @@ -1032,9 +1061,9 @@ Extents Texture::getAttachmentSize(const gl::FramebufferAttachment::Target &targ return mState.getImageDesc(target.textureIndex().type, target.textureIndex().mipIndex).size; } -GLenum Texture::getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const +const Format &Texture::getAttachmentFormat(const gl::FramebufferAttachment::Target &target) const { - return getInternalFormat(target.textureIndex().type, target.textureIndex().mipIndex); + return getFormat(target.textureIndex().type, target.textureIndex().mipIndex); } GLsizei Texture::getAttachmentSamples(const gl::FramebufferAttachment::Target &/*target*/) const diff --git a/chromium/third_party/angle/src/libANGLE/Texture.h b/chromium/third_party/angle/src/libANGLE/Texture.h index 3e5a31139d7..36cef52cde7 100644 --- a/chromium/third_party/angle/src/libANGLE/Texture.h +++ b/chromium/third_party/angle/src/libANGLE/Texture.h @@ -22,6 +22,7 @@ #include "libANGLE/Image.h" #include "libANGLE/Stream.h" #include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" namespace egl { @@ -47,13 +48,13 @@ bool IsMipmapFiltered(const SamplerState &samplerState); struct ImageDesc final { ImageDesc(); - ImageDesc(const Extents &size, GLenum internalFormat); + ImageDesc(const Extents &size, const Format &format); ImageDesc(const ImageDesc &other) = default; ImageDesc &operator=(const ImageDesc &other) = default; Extents size; - GLenum internalFormat; + Format format; }; struct SwizzleState final @@ -118,7 +119,7 @@ struct TextureState final : public angle::NonCopyable void setImageDescChain(GLuint baselevel, GLuint maxLevel, Extents baseSize, - GLenum sizedInternalFormat); + const Format &format); void clearImageDesc(GLenum target, size_t level); void clearImageDescs(); @@ -236,7 +237,7 @@ class Texture final : public egl::ImageSibling, size_t getWidth(GLenum target, size_t level) const; size_t getHeight(GLenum target, size_t level) const; size_t getDepth(GLenum target, size_t level) const; - GLenum getInternalFormat(GLenum target, size_t level) const; + const Format &getFormat(GLenum target, size_t level) const; bool isMipmapComplete() const; @@ -282,6 +283,19 @@ class Texture final : public egl::ImageSibling, const Rectangle &sourceArea, const Framebuffer *source); + Error copyTexture(GLenum internalFormat, + GLenum type, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Texture *source); + Error copySubTexture(const Offset &destOffset, + const Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Texture *source); + Error setStorage(GLenum target, GLsizei levels, GLenum internalFormat, const Extents &size); Error setEGLImageTarget(GLenum target, egl::Image *imageTarget); @@ -296,7 +310,7 @@ class Texture final : public egl::ImageSibling, // FramebufferAttachmentObject implementation Extents getAttachmentSize(const FramebufferAttachment::Target &target) const override; - GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &target) const override; + const Format &getAttachmentFormat(const FramebufferAttachment::Target &target) const override; GLsizei getAttachmentSamples(const FramebufferAttachment::Target &target) const override; void onAttach() override; diff --git a/chromium/third_party/angle/src/libANGLE/TransformFeedback.cpp b/chromium/third_party/angle/src/libANGLE/TransformFeedback.cpp index 22341547446..293c91b3132 100644 --- a/chromium/third_party/angle/src/libANGLE/TransformFeedback.cpp +++ b/chromium/third_party/angle/src/libANGLE/TransformFeedback.cpp @@ -16,31 +16,51 @@ namespace gl { -TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps) - : RefCountObject(id), - mImplementation(implFactory->createTransformFeedback()), - mLabel(), +TransformFeedbackState::TransformFeedbackState(size_t maxIndexedBuffers) + : mLabel(), mActive(false), mPrimitiveMode(GL_NONE), mPaused(false), mProgram(nullptr), mGenericBuffer(), - mIndexedBuffers(caps.maxTransformFeedbackSeparateAttributes) + mIndexedBuffers(maxIndexedBuffers) +{ +} + +const BindingPointer<Buffer> &TransformFeedbackState::getGenericBuffer() const +{ + return mGenericBuffer; +} + +const OffsetBindingPointer<Buffer> &TransformFeedbackState::getIndexedBuffer(size_t idx) const +{ + return mIndexedBuffers[idx]; +} + +const std::vector<OffsetBindingPointer<Buffer>> &TransformFeedbackState::getIndexedBuffers() const +{ + return mIndexedBuffers; +} + +TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps) + : RefCountObject(id), + mState(caps.maxTransformFeedbackSeparateAttributes), + mImplementation(implFactory->createTransformFeedback(mState)) { ASSERT(mImplementation != nullptr); } TransformFeedback::~TransformFeedback() { - if (mProgram) + if (mState.mProgram) { - mProgram->release(); - mProgram = nullptr; + mState.mProgram->release(); + mState.mProgram = nullptr; } - mGenericBuffer.set(nullptr); - for (size_t i = 0; i < mIndexedBuffers.size(); i++) + mState.mGenericBuffer.set(nullptr); + for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++) { - mIndexedBuffers[i].set(nullptr); + mState.mIndexedBuffers[i].set(nullptr); } SafeDelete(mImplementation); @@ -48,129 +68,129 @@ TransformFeedback::~TransformFeedback() void TransformFeedback::setLabel(const std::string &label) { - mLabel = label; + mState.mLabel = label; } const std::string &TransformFeedback::getLabel() const { - return mLabel; + return mState.mLabel; } void TransformFeedback::begin(GLenum primitiveMode, Program *program) { - mActive = true; - mPrimitiveMode = primitiveMode; - mPaused = false; + mState.mActive = true; + mState.mPrimitiveMode = primitiveMode; + mState.mPaused = false; mImplementation->begin(primitiveMode); bindProgram(program); } void TransformFeedback::end() { - mActive = false; - mPrimitiveMode = GL_NONE; - mPaused = false; + mState.mActive = false; + mState.mPrimitiveMode = GL_NONE; + mState.mPaused = false; mImplementation->end(); - if (mProgram) + if (mState.mProgram) { - mProgram->release(); - mProgram = nullptr; + mState.mProgram->release(); + mState.mProgram = nullptr; } } void TransformFeedback::pause() { - mPaused = true; + mState.mPaused = true; mImplementation->pause(); } void TransformFeedback::resume() { - mPaused = false; + mState.mPaused = false; mImplementation->resume(); } bool TransformFeedback::isActive() const { - return mActive; + return mState.mActive; } bool TransformFeedback::isPaused() const { - return mPaused; + return mState.mPaused; } GLenum TransformFeedback::getPrimitiveMode() const { - return mPrimitiveMode; + return mState.mPrimitiveMode; } void TransformFeedback::bindProgram(Program *program) { - if (mProgram != program) + if (mState.mProgram != program) { - if (mProgram != nullptr) + if (mState.mProgram != nullptr) { - mProgram->release(); + mState.mProgram->release(); } - mProgram = program; - if (mProgram != nullptr) + mState.mProgram = program; + if (mState.mProgram != nullptr) { - mProgram->addRef(); + mState.mProgram->addRef(); } } } bool TransformFeedback::hasBoundProgram(GLuint program) const { - return mProgram != nullptr && mProgram->id() == program; + return mState.mProgram != nullptr && mState.mProgram->id() == program; } void TransformFeedback::bindGenericBuffer(Buffer *buffer) { - mGenericBuffer.set(buffer); - mImplementation->bindGenericBuffer(mGenericBuffer); + mState.mGenericBuffer.set(buffer); + mImplementation->bindGenericBuffer(mState.mGenericBuffer); } void TransformFeedback::detachBuffer(GLuint bufferName) { - for (size_t index = 0; index < mIndexedBuffers.size(); index++) + for (size_t index = 0; index < mState.mIndexedBuffers.size(); index++) { - if (mIndexedBuffers[index].id() == bufferName) + if (mState.mIndexedBuffers[index].id() == bufferName) { - mIndexedBuffers[index].set(nullptr); - mImplementation->bindIndexedBuffer(index, mIndexedBuffers[index]); + mState.mIndexedBuffers[index].set(nullptr); + mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]); } } - if (mGenericBuffer.id() == bufferName) + if (mState.mGenericBuffer.id() == bufferName) { - mGenericBuffer.set(nullptr); - mImplementation->bindGenericBuffer(mGenericBuffer); + mState.mGenericBuffer.set(nullptr); + mImplementation->bindGenericBuffer(mState.mGenericBuffer); } } const BindingPointer<Buffer> &TransformFeedback::getGenericBuffer() const { - return mGenericBuffer; + return mState.mGenericBuffer; } void TransformFeedback::bindIndexedBuffer(size_t index, Buffer *buffer, size_t offset, size_t size) { - ASSERT(index < mIndexedBuffers.size()); - mIndexedBuffers[index].set(buffer, offset, size); - mImplementation->bindIndexedBuffer(index, mIndexedBuffers[index]); + ASSERT(index < mState.mIndexedBuffers.size()); + mState.mIndexedBuffers[index].set(buffer, offset, size); + mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]); } const OffsetBindingPointer<Buffer> &TransformFeedback::getIndexedBuffer(size_t index) const { - ASSERT(index < mIndexedBuffers.size()); - return mIndexedBuffers[index]; + ASSERT(index < mState.mIndexedBuffers.size()); + return mState.mIndexedBuffers[index]; } size_t TransformFeedback::getIndexedBufferCount() const { - return mIndexedBuffers.size(); + return mState.mIndexedBuffers.size(); } rx::TransformFeedbackImpl *TransformFeedback::getImplementation() diff --git a/chromium/third_party/angle/src/libANGLE/TransformFeedback.h b/chromium/third_party/angle/src/libANGLE/TransformFeedback.h index c120710a25b..5b1eb34bff6 100644 --- a/chromium/third_party/angle/src/libANGLE/TransformFeedback.h +++ b/chromium/third_party/angle/src/libANGLE/TransformFeedback.h @@ -26,6 +26,30 @@ class Buffer; struct Caps; class Program; +class TransformFeedbackState final : public angle::NonCopyable +{ + public: + TransformFeedbackState(size_t maxIndexedBuffers); + + const BindingPointer<Buffer> &getGenericBuffer() const; + const OffsetBindingPointer<Buffer> &getIndexedBuffer(size_t idx) const; + const std::vector<OffsetBindingPointer<Buffer>> &getIndexedBuffers() const; + + private: + friend class TransformFeedback; + + std::string mLabel; + + bool mActive; + GLenum mPrimitiveMode; + bool mPaused; + + Program *mProgram; + + BindingPointer<Buffer> mGenericBuffer; + std::vector<OffsetBindingPointer<Buffer>> mIndexedBuffers; +}; + class TransformFeedback final : public RefCountObject, public LabeledObject { public: @@ -61,18 +85,8 @@ class TransformFeedback final : public RefCountObject, public LabeledObject private: void bindProgram(Program *program); + TransformFeedbackState mState; rx::TransformFeedbackImpl* mImplementation; - - std::string mLabel; - - bool mActive; - GLenum mPrimitiveMode; - bool mPaused; - - Program *mProgram; - - BindingPointer<Buffer> mGenericBuffer; - std::vector<OffsetBindingPointer<Buffer>> mIndexedBuffers; }; } diff --git a/chromium/third_party/angle/src/libANGLE/TransformFeedback_unittest.cpp b/chromium/third_party/angle/src/libANGLE/TransformFeedback_unittest.cpp index d173686ea20..07a0959e2c9 100644 --- a/chromium/third_party/angle/src/libANGLE/TransformFeedback_unittest.cpp +++ b/chromium/third_party/angle/src/libANGLE/TransformFeedback_unittest.cpp @@ -14,12 +14,18 @@ #include "tests/angle_unittests_utils.h" using ::testing::_; +using ::testing::get; using ::testing::Return; using ::testing::SetArgumentPointee; namespace { +ACTION(CreateMockTransformFeedbackImpl) +{ + return new rx::MockTransformFeedbackImpl(arg0); +} + class TransformFeedbackTest : public testing::Test { protected: @@ -27,17 +33,18 @@ class TransformFeedbackTest : public testing::Test void SetUp() override { - mImpl = new rx::MockTransformFeedbackImpl; - EXPECT_CALL(mMockFactory, createTransformFeedback()) - .WillOnce(Return(mImpl)) + EXPECT_CALL(mMockFactory, createTransformFeedback(_)) + .WillOnce(CreateMockTransformFeedbackImpl()) .RetiresOnSaturation(); // Set a reasonable number of tf attributes mCaps.maxTransformFeedbackSeparateAttributes = 8; - EXPECT_CALL(*mImpl, destructor()); mFeedback = new gl::TransformFeedback(&mMockFactory, 1, mCaps); mFeedback->addRef(); + + mImpl = rx::GetImplAs<rx::MockTransformFeedbackImpl>(mFeedback); + EXPECT_CALL(*mImpl, destructor()); } void TearDown() override diff --git a/chromium/third_party/angle/src/libANGLE/Uniform.cpp b/chromium/third_party/angle/src/libANGLE/Uniform.cpp index bfae3c014ff..9b4b47aa290 100644 --- a/chromium/third_party/angle/src/libANGLE/Uniform.cpp +++ b/chromium/third_party/angle/src/libANGLE/Uniform.cpp @@ -121,7 +121,12 @@ const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const } UniformBlock::UniformBlock() - : isArray(false), arrayElement(0), dataSize(0), vertexStaticUse(false), fragmentStaticUse(false) + : isArray(false), + arrayElement(0), + dataSize(0), + vertexStaticUse(false), + fragmentStaticUse(false), + computeStaticUse(false) { } @@ -131,7 +136,8 @@ UniformBlock::UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned i arrayElement(arrayElementIn), dataSize(0), vertexStaticUse(false), - fragmentStaticUse(false) + fragmentStaticUse(false), + computeStaticUse(false) { } diff --git a/chromium/third_party/angle/src/libANGLE/Uniform.h b/chromium/third_party/angle/src/libANGLE/Uniform.h index e62a583f3dd..4d7d24e3bc0 100644 --- a/chromium/third_party/angle/src/libANGLE/Uniform.h +++ b/chromium/third_party/angle/src/libANGLE/Uniform.h @@ -63,6 +63,7 @@ struct UniformBlock bool vertexStaticUse; bool fragmentStaticUse; + bool computeStaticUse; std::vector<unsigned int> memberUniformIndexes; }; diff --git a/chromium/third_party/angle/src/libANGLE/Workarounds.h b/chromium/third_party/angle/src/libANGLE/Workarounds.h new file mode 100644 index 00000000000..c5533c1c8f6 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/Workarounds.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Workarounds.h: Workarounds for driver bugs and other behaviors seen +// on all platforms. + +#ifndef LIBANGLE_WORKAROUNDS_H_ +#define LIBANGLE_WORKAROUNDS_H_ + +namespace gl +{ + +struct Workarounds +{ + // Force the context to be lost (via KHR_robustness) if a GL_OUT_OF_MEMORY error occurs. The + // driver may be in an inconsistent state if this happens, and some users of ANGLE rely on this + // notification to prevent further execution. + bool loseContextOnOutOfMemory = false; +}; +} // namespace gl + +#endif // LIBANGLE_WORKAROUNDS_H_ diff --git a/chromium/third_party/angle/src/libANGLE/angletypes.h b/chromium/third_party/angle/src/libANGLE/angletypes.h index c5613526197..0c5c7eaa7bd 100644 --- a/chromium/third_party/angle/src/libANGLE/angletypes.h +++ b/chromium/third_party/angle/src/libANGLE/angletypes.h @@ -45,28 +45,6 @@ enum SamplerType SAMPLER_VERTEX }; -template <typename T> -struct Color -{ - T red; - T green; - T blue; - T alpha; - - Color() : red(0), green(0), blue(0), alpha(0) { } - Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a) { } -}; - -template <typename T> -bool operator==(const Color<T> &a, const Color<T> &b); - -template <typename T> -bool operator!=(const Color<T> &a, const Color<T> &b); - -typedef Color<float> ColorF; -typedef Color<int> ColorI; -typedef Color<unsigned int> ColorUI; - struct Rectangle { Rectangle() : x(0), y(0), width(0), height(0) {} @@ -219,59 +197,39 @@ struct SamplerState bool operator==(const SamplerState &a, const SamplerState &b); bool operator!=(const SamplerState &a, const SamplerState &b); -struct PixelUnpackState +struct PixelStoreStateBase { BindingPointer<Buffer> pixelBuffer; - GLint alignment; - GLint rowLength; - GLint skipRows; - GLint skipPixels; - GLint imageHeight; - GLint skipImages; - - PixelUnpackState() - : alignment(4), - rowLength(0), - skipRows(0), - skipPixels(0), - imageHeight(0), - skipImages(0) - {} + GLint alignment = 4; + GLint rowLength = 0; + GLint skipRows = 0; + GLint skipPixels = 0; + GLint imageHeight = 0; + GLint skipImages = 0; +}; + +struct PixelUnpackState : PixelStoreStateBase +{ + PixelUnpackState() {} PixelUnpackState(GLint alignmentIn, GLint rowLengthIn) - : alignment(alignmentIn), - rowLength(rowLengthIn), - skipRows(0), - skipPixels(0), - imageHeight(0), - skipImages(0) - {} + { + alignment = alignmentIn; + rowLength = rowLengthIn; + } }; -struct PixelPackState +struct PixelPackState : PixelStoreStateBase { - BindingPointer<Buffer> pixelBuffer; - GLint alignment; - bool reverseRowOrder; - GLint rowLength; - GLint skipRows; - GLint skipPixels; - - PixelPackState() - : alignment(4), - reverseRowOrder(false), - rowLength(0), - skipRows(0), - skipPixels(0) - {} - - explicit PixelPackState(GLint alignmentIn, bool reverseRowOrderIn) - : alignment(alignmentIn), - reverseRowOrder(reverseRowOrderIn), - rowLength(0), - skipRows(0), - skipPixels(0) - {} + PixelPackState() {} + + PixelPackState(GLint alignmentIn, bool reverseRowOrderIn) + : reverseRowOrder(reverseRowOrderIn) + { + alignment = alignmentIn; + } + + bool reverseRowOrder = false; }; // Used in Program and VertexArray. diff --git a/chromium/third_party/angle/src/libANGLE/angletypes.inl b/chromium/third_party/angle/src/libANGLE/angletypes.inl index f14a9b624d8..3371286b93b 100644 --- a/chromium/third_party/angle/src/libANGLE/angletypes.inl +++ b/chromium/third_party/angle/src/libANGLE/angletypes.inl @@ -9,21 +9,6 @@ namespace gl { -template <typename T> -bool operator==(const Color<T> &a, const Color<T> &b) -{ - return a.red == b.red && - a.green == b.green && - a.blue == b.blue && - a.alpha == b.alpha; -} - -template <typename T> -bool operator!=(const Color<T> &a, const Color<T> &b) -{ - return !(a == b); -} - inline bool operator==(const Rectangle &a, const Rectangle &b) { return a.x == b.x && diff --git a/chromium/third_party/angle/src/libANGLE/format_map_autogen.cpp b/chromium/third_party/angle/src/libANGLE/format_map_autogen.cpp new file mode 100644 index 00000000000..481900bf113 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/format_map_autogen.cpp @@ -0,0 +1,373 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_format_map.py using data from format_map_data.json. +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// format_map: +// Determining the sized internal format from a (format,type) pair. + +#include "angle_gl.h" +#include "common/debug.h" + +namespace gl +{ + +GLenum GetSizedFormatInternal(GLenum format, GLenum type) +{ + switch (format) + { + case GL_ALPHA: + switch (type) + { + case GL_FLOAT: + return GL_ALPHA32F_EXT; + case GL_HALF_FLOAT: + return GL_ALPHA16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_ALPHA16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_ALPHA8_EXT; + default: + break; + } + break; + + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_BGRA8_EXT; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + return GL_BGR5_A1_ANGLEX; + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return GL_BGRA4_ANGLEX; + case GL_UNSIGNED_SHORT_5_6_5: + return GL_BGR565_ANGLEX; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; + default: + break; + } + break; + + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_FLOAT: + return GL_DEPTH_COMPONENT32F; + case GL_UNSIGNED_INT: + return GL_DEPTH_COMPONENT32_OES; + case GL_UNSIGNED_SHORT: + return GL_DEPTH_COMPONENT16; + default: + break; + } + break; + + case GL_DEPTH_STENCIL: + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return GL_DEPTH32F_STENCIL8; + case GL_UNSIGNED_INT_24_8: + return GL_DEPTH24_STENCIL8; + default: + break; + } + break; + + case GL_LUMINANCE: + switch (type) + { + case GL_FLOAT: + return GL_LUMINANCE32F_EXT; + case GL_HALF_FLOAT: + return GL_LUMINANCE16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_LUMINANCE16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_LUMINANCE8_EXT; + default: + break; + } + break; + + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_FLOAT: + return GL_LUMINANCE_ALPHA32F_EXT; + case GL_HALF_FLOAT: + return GL_LUMINANCE_ALPHA16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_LUMINANCE_ALPHA16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_LUMINANCE8_ALPHA8_EXT; + default: + break; + } + break; + + case GL_RED: + switch (type) + { + case GL_BYTE: + return GL_R8_SNORM; + case GL_FLOAT: + return GL_R32F; + case GL_HALF_FLOAT: + return GL_R16F; + case GL_HALF_FLOAT_OES: + return GL_R16F; + case GL_SHORT: + return GL_R16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_R8; + case GL_UNSIGNED_SHORT: + return GL_R16_EXT; + default: + break; + } + break; + + case GL_RED_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_R8I; + case GL_INT: + return GL_R32I; + case GL_SHORT: + return GL_R16I; + case GL_UNSIGNED_BYTE: + return GL_R8UI; + case GL_UNSIGNED_INT: + return GL_R32UI; + case GL_UNSIGNED_SHORT: + return GL_R16UI; + default: + break; + } + break; + + case GL_RG: + switch (type) + { + case GL_BYTE: + return GL_RG8_SNORM; + case GL_FLOAT: + return GL_RG32F; + case GL_HALF_FLOAT: + return GL_RG16F; + case GL_HALF_FLOAT_OES: + return GL_RG16F; + case GL_SHORT: + return GL_RG16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RG8; + case GL_UNSIGNED_SHORT: + return GL_RG16_EXT; + default: + break; + } + break; + + case GL_RGB: + switch (type) + { + case GL_BYTE: + return GL_RGB8_SNORM; + case GL_FLOAT: + return GL_RGB32F; + case GL_HALF_FLOAT: + return GL_RGB16F; + case GL_HALF_FLOAT_OES: + return GL_RGB16F; + case GL_SHORT: + return GL_RGB16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RGB8; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return GL_R11F_G11F_B10F; + case GL_UNSIGNED_INT_5_9_9_9_REV: + return GL_RGB9_E5; + case GL_UNSIGNED_SHORT: + return GL_RGB16_EXT; + case GL_UNSIGNED_SHORT_5_6_5: + return GL_RGB565; + default: + break; + } + break; + + case GL_RGBA: + switch (type) + { + case GL_BYTE: + return GL_RGBA8_SNORM; + case GL_FLOAT: + return GL_RGBA32F; + case GL_HALF_FLOAT: + return GL_RGBA16F; + case GL_HALF_FLOAT_OES: + return GL_RGBA16F; + case GL_SHORT: + return GL_RGBA16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RGBA8; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_RGB10_A2; + case GL_UNSIGNED_SHORT: + return GL_RGBA16_EXT; + case GL_UNSIGNED_SHORT_4_4_4_4: + return GL_RGBA4; + case GL_UNSIGNED_SHORT_5_5_5_1: + return GL_RGB5_A1; + default: + break; + } + break; + + case GL_RGBA_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RGBA8I; + case GL_INT: + return GL_RGBA32I; + case GL_SHORT: + return GL_RGBA16I; + case GL_UNSIGNED_BYTE: + return GL_RGBA8UI; + case GL_UNSIGNED_INT: + return GL_RGBA32UI; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_RGB10_A2UI; + case GL_UNSIGNED_SHORT: + return GL_RGBA16UI; + default: + break; + } + break; + + case GL_RGB_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RGB8I; + case GL_INT: + return GL_RGB32I; + case GL_SHORT: + return GL_RGB16I; + case GL_UNSIGNED_BYTE: + return GL_RGB8UI; + case GL_UNSIGNED_INT: + return GL_RGB32UI; + case GL_UNSIGNED_SHORT: + return GL_RGB16UI; + default: + break; + } + break; + + case GL_RG_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RG8I; + case GL_INT: + return GL_RG32I; + case GL_SHORT: + return GL_RG16I; + case GL_UNSIGNED_BYTE: + return GL_RG8UI; + case GL_UNSIGNED_INT: + return GL_RG32UI; + case GL_UNSIGNED_SHORT: + return GL_RG16UI; + default: + break; + } + break; + + case GL_SRGB_ALPHA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_SRGB8_ALPHA8; + default: + break; + } + break; + + case GL_SRGB_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_SRGB8; + default: + break; + } + break; + + case GL_STENCIL: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_STENCIL_INDEX8; + default: + break; + } + break; + + case GL_NONE: + return GL_NONE; + + default: + break; + } + + return GL_NONE; +} + +} // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/format_map_data.json b/chromium/third_party/angle/src/libANGLE/format_map_data.json new file mode 100644 index 00000000000..3d6ad6c3cde --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/format_map_data.json @@ -0,0 +1,130 @@ +{ + "GL_RGBA": { + "GL_UNSIGNED_BYTE": "GL_RGBA8", + "GL_UNSIGNED_SHORT": "GL_RGBA16_EXT", + "GL_BYTE": "GL_RGBA8_SNORM", + "GL_SHORT": "GL_RGBA16_SNORM_EXT", + "GL_UNSIGNED_SHORT_4_4_4_4": "GL_RGBA4", + "GL_UNSIGNED_SHORT_5_5_5_1": "GL_RGB5_A1", + "GL_UNSIGNED_INT_2_10_10_10_REV": "GL_RGB10_A2", + "GL_FLOAT": "GL_RGBA32F", + "GL_HALF_FLOAT": "GL_RGBA16F", + "GL_HALF_FLOAT_OES": "GL_RGBA16F" + }, + "GL_RGBA_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_RGBA8UI", + "GL_BYTE": "GL_RGBA8I", + "GL_UNSIGNED_SHORT": "GL_RGBA16UI", + "GL_SHORT": "GL_RGBA16I", + "GL_UNSIGNED_INT": "GL_RGBA32UI", + "GL_INT": "GL_RGBA32I", + "GL_UNSIGNED_INT_2_10_10_10_REV": "GL_RGB10_A2UI" + }, + "GL_RGB": { + "GL_UNSIGNED_BYTE": "GL_RGB8", + "GL_UNSIGNED_SHORT": "GL_RGB16_EXT", + "GL_BYTE": "GL_RGB8_SNORM", + "GL_SHORT": "GL_RGB16_SNORM_EXT", + "GL_UNSIGNED_SHORT_5_6_5": "GL_RGB565", + "GL_UNSIGNED_INT_10F_11F_11F_REV": "GL_R11F_G11F_B10F", + "GL_UNSIGNED_INT_5_9_9_9_REV": "GL_RGB9_E5", + "GL_FLOAT": "GL_RGB32F", + "GL_HALF_FLOAT": "GL_RGB16F", + "GL_HALF_FLOAT_OES": "GL_RGB16F" + }, + "GL_RGB_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_RGB8UI", + "GL_BYTE": "GL_RGB8I", "GL_UNSIGNED_SHORT": "GL_RGB16UI", + "GL_SHORT": "GL_RGB16I", + "GL_UNSIGNED_INT": "GL_RGB32UI", + "GL_INT": "GL_RGB32I" + }, + "GL_RG": { + "GL_UNSIGNED_BYTE": "GL_RG8", + "GL_UNSIGNED_SHORT": "GL_RG16_EXT", + "GL_BYTE": "GL_RG8_SNORM", + "GL_SHORT": "GL_RG16_SNORM_EXT", + "GL_FLOAT": "GL_RG32F", + "GL_HALF_FLOAT": "GL_RG16F", + "GL_HALF_FLOAT_OES": "GL_RG16F" + }, + "GL_RG_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_RG8UI", + "GL_BYTE": "GL_RG8I", + "GL_UNSIGNED_SHORT": "GL_RG16UI", + "GL_SHORT": "GL_RG16I", + "GL_UNSIGNED_INT": "GL_RG32UI", + "GL_INT": "GL_RG32I" + }, + "GL_RED": { + "GL_UNSIGNED_BYTE": "GL_R8", + "GL_UNSIGNED_SHORT": "GL_R16_EXT", + "GL_BYTE": "GL_R8_SNORM", + "GL_SHORT": "GL_R16_SNORM_EXT", + "GL_FLOAT": "GL_R32F", + "GL_HALF_FLOAT": "GL_R16F", + "GL_HALF_FLOAT_OES": "GL_R16F" + }, + "GL_RED_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_R8UI", + "GL_BYTE": "GL_R8I", + "GL_UNSIGNED_SHORT": "GL_R16UI", + "GL_SHORT": "GL_R16I", + "GL_UNSIGNED_INT": "GL_R32UI", + "GL_INT": "GL_R32I" + }, + "GL_LUMINANCE_ALPHA": { + "GL_UNSIGNED_BYTE": "GL_LUMINANCE8_ALPHA8_EXT", + "GL_FLOAT": "GL_LUMINANCE_ALPHA32F_EXT", + "GL_HALF_FLOAT": "GL_LUMINANCE_ALPHA16F_EXT", + "GL_HALF_FLOAT_OES": "GL_LUMINANCE_ALPHA16F_EXT" + }, + "GL_LUMINANCE": { + "GL_UNSIGNED_BYTE": "GL_LUMINANCE8_EXT", + "GL_FLOAT": "GL_LUMINANCE32F_EXT", + "GL_HALF_FLOAT": "GL_LUMINANCE16F_EXT", + "GL_HALF_FLOAT_OES": "GL_LUMINANCE16F_EXT" + }, + "GL_ALPHA": { + "GL_UNSIGNED_BYTE": "GL_ALPHA8_EXT", + "GL_FLOAT": "GL_ALPHA32F_EXT", + "GL_HALF_FLOAT": "GL_ALPHA16F_EXT", + "GL_HALF_FLOAT_OES": "GL_ALPHA16F_EXT" + }, + "GL_BGRA_EXT": { + "GL_UNSIGNED_BYTE": "GL_BGRA8_EXT", + "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": "GL_BGRA4_ANGLEX", + "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": "GL_BGR5_A1_ANGLEX", + "GL_UNSIGNED_SHORT_5_6_5": "GL_BGR565_ANGLEX" + }, + "GL_SRGB_EXT": { + "GL_UNSIGNED_BYTE": "GL_SRGB8" + }, + "GL_SRGB_ALPHA_EXT": { + "GL_UNSIGNED_BYTE": "GL_SRGB8_ALPHA8" + }, + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGB_S3TC_DXT1_EXT" + }, + "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" + }, + "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE" + }, + "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE" + }, + "GL_DEPTH_COMPONENT": { + "GL_UNSIGNED_SHORT": "GL_DEPTH_COMPONENT16", + "GL_UNSIGNED_INT": "GL_DEPTH_COMPONENT32_OES", + "GL_FLOAT": "GL_DEPTH_COMPONENT32F" + }, + "GL_STENCIL": { + "GL_UNSIGNED_BYTE": "GL_STENCIL_INDEX8" + }, + "GL_DEPTH_STENCIL": { + "GL_UNSIGNED_INT_24_8": "GL_DEPTH24_STENCIL8", + "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": "GL_DEPTH32F_STENCIL8" + } +} diff --git a/chromium/third_party/angle/src/libANGLE/formatutils.cpp b/chromium/third_party/angle/src/libANGLE/formatutils.cpp index c9533aa24fc..ff285dd9a9f 100644 --- a/chromium/third_party/angle/src/libANGLE/formatutils.cpp +++ b/chromium/third_party/angle/src/libANGLE/formatutils.cpp @@ -19,9 +19,14 @@ namespace gl // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid // format and type combinations. +GLenum GetSizedFormatInternal(GLenum format, GLenum type); -typedef std::pair<FormatType, GLenum> FormatPair; -typedef std::map<FormatType, GLenum> FormatMap; +namespace +{ +typedef std::pair<GLenum, InternalFormat> InternalFormatInfoPair; +typedef std::map<GLenum, InternalFormat> InternalFormatInfoMap; + +} // anonymous namespace FormatType::FormatType() : format(GL_NONE), type(GL_NONE) { @@ -38,113 +43,6 @@ bool FormatType::operator<(const FormatType &other) const return type < other.type; } -// A helper function to insert data into the format map with fewer characters. -static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat) -{ - map->insert(FormatPair(FormatType(format, type), internalFormat)); -} - -FormatMap BuildFormatMap() -{ - FormatMap map; - - // | Format | Type | Internal format | - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8); - InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM); - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4); - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1); - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2); - InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F); - InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F); - InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F); - - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI); - - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8); - InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM); - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565); - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F); - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5); - InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F); - InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F); - InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F); - - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I); - - InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8); - InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM); - InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F); - InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F); - InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F); - - InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I); - - InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8); - InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM); - InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F); - InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F); - InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F); - - InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I); - - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT); - - InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT); - InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX); - InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX); - - InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8); - InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8); - - InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); - - InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F); - - InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8); - - InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8); - InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8); - - return map; -} - Type::Type() : bytes(0), bytesShift(0), @@ -283,7 +181,8 @@ static bool FloatRenderableSupportRG(GLuint clientVersion, const Extensions &ext } InternalFormat::InternalFormat() - : redBits(0), + : internalFormat(GL_NONE), + redBits(0), greenBits(0), blueBits(0), luminanceBits(0), @@ -306,25 +205,126 @@ InternalFormat::InternalFormat() { } -static InternalFormat UnsizedFormat(GLenum format, InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +bool InternalFormat::isLUMA() const +{ + return ((redBits + greenBits + blueBits + depthBits + stencilBits) == 0 && + (luminanceBits + alphaBits) > 0); +} + +GLenum InternalFormat::getReadPixelsFormat() const +{ + return format; +} + +GLenum InternalFormat::getReadPixelsType() const +{ + switch (type) + { + case GL_HALF_FLOAT: + // The internal format may have a type of GL_HALF_FLOAT but when exposing this type as + // the IMPLEMENTATION_READ_TYPE, only HALF_FLOAT_OES is allowed by + // OES_texture_half_float + return GL_HALF_FLOAT_OES; + + default: + return type; + } +} + +Format::Format(GLenum internalFormat) : Format(GetInternalFormatInfo(internalFormat)) +{ +} + +Format::Format(const InternalFormat &internalFormat) + : info(&internalFormat), format(info->format), type(info->type), sized(true) +{ + ASSERT((info->pixelBytes > 0 && format != GL_NONE && type != GL_NONE) || + internalFormat.format == GL_NONE); +} + +Format::Format(GLenum internalFormat, GLenum format, GLenum type) + : info(nullptr), format(format), type(type), sized(false) +{ + const auto &plainInfo = GetInternalFormatInfo(internalFormat); + sized = plainInfo.pixelBytes > 0; + info = (sized ? &plainInfo : &GetInternalFormatInfo(GetSizedFormatInternal(format, type))); + ASSERT(format == GL_NONE || info->pixelBytes > 0); +} + +Format::Format(const Format &other) = default; +Format &Format::operator=(const Format &other) = default; + +GLenum Format::asSized() const +{ + return sized ? info->internalFormat : GetSizedFormatInternal(format, type); +} + +bool Format::valid() const +{ + return info->format != GL_NONE; +} + +// static +bool Format::SameSized(const Format &a, const Format &b) +{ + return (a.info == b.info); +} + +// static +Format Format::Invalid() +{ + static Format invalid(GL_NONE, GL_NONE, GL_NONE); + return invalid; +} + +bool InternalFormat::operator==(const InternalFormat &other) const +{ + // We assume there are no duplicates. + ASSERT((this == &other) == (internalFormat == other.internalFormat)); + return internalFormat == other.internalFormat; +} + +bool InternalFormat::operator!=(const InternalFormat &other) const +{ + // We assume there are no duplicates. + ASSERT((this != &other) == (internalFormat != other.internalFormat)); + return internalFormat != other.internalFormat; +} + +static void AddUnsizedFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + GLenum format, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction renderSupport, + InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; formatInfo.format = format; formatInfo.textureSupport = textureSupport; formatInfo.renderSupport = renderSupport; formatInfo.filterSupport = filterSupport; - return formatInfo; + ASSERT(map->count(internalFormat) == 0); + (*map)[internalFormat] = formatInfo; } -static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared, - GLenum format, GLenum type, GLenum componentType, bool srgb, - InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +void AddRGBAFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + GLuint red, + GLuint green, + GLuint blue, + GLuint alpha, + GLuint shared, + GLenum format, + GLenum type, + GLenum componentType, + bool srgb, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction renderSupport, + InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; formatInfo.redBits = red; formatInfo.greenBits = green; formatInfo.blueBits = blue; @@ -339,7 +339,8 @@ static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint a formatInfo.textureSupport = textureSupport; formatInfo.renderSupport = renderSupport; formatInfo.filterSupport = filterSupport; - return formatInfo; + ASSERT(map->count(internalFormat) == 0); + (*map)[internalFormat] = formatInfo; } static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType, @@ -348,6 +349,7 @@ static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = GetSizedFormatInternal(format, type); formatInfo.luminanceBits = luminance; formatInfo.alphaBits = alpha; formatInfo.pixelBytes = (luminance + alpha) / 8; @@ -362,12 +364,20 @@ static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, return formatInfo; } -static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format, - GLenum type, GLenum componentType, InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +void AddDepthStencilFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + GLuint depthBits, + GLuint stencilBits, + GLuint unusedBits, + GLenum format, + GLenum type, + GLenum componentType, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction renderSupport, + InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; formatInfo.depthBits = depthBits; formatInfo.stencilBits = stencilBits; formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8; @@ -379,7 +389,8 @@ static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, G formatInfo.textureSupport = textureSupport; formatInfo.renderSupport = renderSupport; formatInfo.filterSupport = filterSupport; - return formatInfo; + ASSERT(map->count(internalFormat) == 0); + (*map)[internalFormat] = formatInfo; } static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize, @@ -389,6 +400,7 @@ static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compr InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = format; formatInfo.compressedBlockWidth = compressedBlockWidth; formatInfo.compressedBlockHeight = compressedBlockHeight; formatInfo.pixelBytes = compressedBlockSize / 8; @@ -404,84 +416,85 @@ static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compr return formatInfo; } -typedef std::pair<GLenum, InternalFormat> InternalFormatInfoPair; -typedef std::map<GLenum, InternalFormat> InternalFormatInfoMap; - static InternalFormatInfoMap BuildInternalFormatInfoMap() { InternalFormatInfoMap map; - // clang-format off // From ES 3.0.1 spec, table 3.12 - map.insert(InternalFormatInfoPair(GL_NONE, InternalFormat())); - - // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_R8, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_R8_SNORM, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG8, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG8_SNORM, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB565, RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA4, RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB5_A1, RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB10_A2, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<3>, RequireES<3>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3>, RequireExt<&Extensions::colorBufferFloat>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB9_E5, RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_R8I, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R8UI, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R16I, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R16UI, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R32I, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R32UI, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG8I, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG8UI, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG16I, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG16UI, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG32I, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG32UI, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8I, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8UI, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB16I, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB16UI, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB32I, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB32UI, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8I, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8UI, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA16I, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA16UI, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA32I, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA32UI, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - - map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_NONE, InternalFormat())); + + // clang-format off + + // | Internal format | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | + AddRGBAFormat(&map, GL_R8, 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported); + AddRGBAFormat(&map, GL_R8_SNORM, 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RG8, 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported); + AddRGBAFormat(&map, GL_RG8_SNORM, 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB8, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB8_SNORM, 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB565, 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA4, 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB5_A1, 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA8, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA8_SNORM, 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB10_A2, 10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<3>, RequireES<3>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB10_A2UI, 10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_SRGB8, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_SRGB8_ALPHA8, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB9_E5, 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_R8I, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_R8UI, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_R16I, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_R16UI, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_R32I, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_R32UI, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RG8I, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RG8UI, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RG16I, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RG16UI, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RG32I, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_R11F_G11F_B10F, 11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3>, RequireExt<&Extensions::colorBufferFloat>, AlwaysSupported); + AddRGBAFormat(&map, GL_RG32UI, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RGB8I, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB8UI, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16I, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16UI, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB32I, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB32UI, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA8I, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA8UI, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA16I, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA16UI, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA32I, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA32UI, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported); + + AddRGBAFormat(&map, GL_BGRA8_EXT, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + AddRGBAFormat(&map, GL_BGRA4_ANGLEX, 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + AddRGBAFormat(&map, GL_BGR5_A1_ANGLEX, 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + + // Special format which is not really supported, so always false for all supports. + AddRGBAFormat(&map, GL_BGR565_ANGLEX, 5, 6, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported); // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float - // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable | - // | | | | | | | type | | | | | - map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ))); + // | Internal format | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable | + // | | | | | | type | | | | | + AddRGBAFormat(&map, GL_R16F, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RG16F, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RGB16F, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RGBA16F, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_R32F, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RG32F, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RGB32F, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RGBA32F, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); // Depth stencil formats - // | Internal format | | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, RequireESOrExt<3, &Extensions::depthTextures>))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, AlwaysSupported ))); - map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, &Extensions::depthTextures>, RequireESOrExtOrExt<3, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported ))); - map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3>, RequireES<3>, AlwaysSupported ))); + // | Internal format | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable | + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT16, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, RequireESOrExt<3, &Extensions::depthTextures>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT24, 24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, 32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, AlwaysSupported ); + AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, &Extensions::depthTextures>, RequireESOrExtOrExt<3, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported ); + AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3>, RequireES<3>, AlwaysSupported ); // STENCIL_INDEX8 is special-cased, see around the bottom of the list. // Luminance alpha formats @@ -497,23 +510,23 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported))); // Unsized formats - // | Internal format | | Format | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_ALPHA, UnsizedFormat(GL_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE, UnsizedFormat(GL_LUMINANCE, RequireES<2>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, UnsizedFormat(GL_LUMINANCE_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RED, UnsizedFormat(GL_RED, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG, UnsizedFormat(GL_RG, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB, UnsizedFormat(GL_RGB, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA, UnsizedFormat(GL_RGBA, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RED_INTEGER, UnsizedFormat(GL_RED_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_RG_INTEGER, UnsizedFormat(GL_RG_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, UnsizedFormat(GL_RGB_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, UnsizedFormat(GL_RGBA_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_BGRA_EXT, UnsizedFormat(GL_BGRA_EXT, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, UnsizedFormat(GL_DEPTH_COMPONENT, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL, UnsizedFormat(GL_DEPTH_STENCIL, RequireESOrExt<3, &Extensions::packedDepthStencil>, RequireESOrExt<3, &Extensions::packedDepthStencil>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB_EXT, UnsizedFormat(GL_RGB, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, UnsizedFormat(GL_RGBA, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported))); + // | Internal format | Format | Supported | Renderable | Filterable | + AddUnsizedFormat(&map, GL_ALPHA, GL_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported); + AddUnsizedFormat(&map, GL_LUMINANCE, GL_LUMINANCE, RequireES<2>, NeverSupported, AlwaysSupported); + AddUnsizedFormat(&map, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported); + AddUnsizedFormat(&map, GL_RED, GL_RED, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported); + AddUnsizedFormat(&map, GL_RG, GL_RG, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported); + AddUnsizedFormat(&map, GL_RGB, GL_RGB, RequireES<2>, RequireES<2>, AlwaysSupported); + AddUnsizedFormat(&map, GL_RGBA, GL_RGBA, RequireES<2>, RequireES<2>, AlwaysSupported); + AddUnsizedFormat(&map, GL_RED_INTEGER, GL_RED_INTEGER, RequireES<3>, NeverSupported, NeverSupported ); + AddUnsizedFormat(&map, GL_RG_INTEGER, GL_RG_INTEGER, RequireES<3>, NeverSupported, NeverSupported ); + AddUnsizedFormat(&map, GL_RGB_INTEGER, GL_RGB_INTEGER, RequireES<3>, NeverSupported, NeverSupported ); + AddUnsizedFormat(&map, GL_RGBA_INTEGER, GL_RGBA_INTEGER, RequireES<3>, NeverSupported, NeverSupported ); + AddUnsizedFormat(&map, GL_BGRA_EXT, GL_BGRA_EXT, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + AddUnsizedFormat(&map, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, RequireES<2>, RequireES<2>, AlwaysSupported); + AddUnsizedFormat(&map, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, RequireESOrExt<3, &Extensions::packedDepthStencil>, RequireESOrExt<3, &Extensions::packedDepthStencil>, AlwaysSupported); + AddUnsizedFormat(&map, GL_SRGB_EXT, GL_RGB, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported); + AddUnsizedFormat(&map, GL_SRGB_ALPHA_EXT, GL_RGBA, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported); // Compressed formats, From ES 3.0.1 spec, table 3.16 // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | @@ -578,22 +591,22 @@ static InternalFormatInfoMap BuildInternalFormatInfoMap() // - Multisampled buffer are disallowed for non-normalized integer component types and we want to support it for STENCIL_INDEX8 // - All other stencil formats (all depth-stencil) are either float or normalized // - It affects only validation of internalformat in RenderbufferStorageMultisample. - // | Internal format | |D |S |X | Format | Type | Component type | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat(0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, NeverSupported))); + // | Internal format |D |S |X | Format | Type | Component type | Supported | Renderable | Filterable | + AddDepthStencilFormat(&map, GL_STENCIL_INDEX8, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, NeverSupported); // From GL_ANGLE_lossy_etc_decode - map.insert(InternalFormatInfoPair(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, CompressedFormat(4, 4, 64, 3, GL_ETC1_RGB8_OES, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported))); + map.insert(InternalFormatInfoPair(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, CompressedFormat(4, 4, 64, 3, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported))); // From GL_EXT_texture_norm16 - // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_R16_EXT, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_R16_SNORM_EXT, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG16_EXT, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG16_SNORM_EXT, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB16_EXT, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB16_SNORM_EXT, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA16_EXT, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA16_SNORM_EXT, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported))); + // | Internal format | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | + AddRGBAFormat(&map, GL_R16_EXT, 16, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported); + AddRGBAFormat(&map, GL_R16_SNORM_EXT, 16, 0, 0, 0, 0, GL_RED, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RG16_EXT, 16, 16, 0, 0, 0, GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported); + AddRGBAFormat(&map, GL_RG16_SNORM_EXT, 16, 16, 0, 0, 0, GL_RG, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB16_EXT, 16, 16, 16, 0, 0, GL_RGB, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB16_SNORM_EXT, 16, 16, 16, 0, 0, GL_RGB, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA16_EXT, 16, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA16_SNORM_EXT, 16, 16, 16, 16, 0, GL_RGBA, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); // clang-format on @@ -610,12 +623,15 @@ static FormatSet BuildAllSizedInternalFormatSet() { FormatSet result; - const InternalFormatInfoMap &formats = GetInternalFormatMap(); - for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++) + for (auto iter : GetInternalFormatMap()) { - if (i->second.pixelBytes > 0) + if (iter.second.pixelBytes > 0) { - result.insert(i->first); + // TODO(jmadill): Fix this hack. + if (iter.first == GL_BGR565_ANGLEX) + continue; + + result.insert(iter.first); } } @@ -681,7 +697,7 @@ const Type &GetTypeInfo(GLenum type) const InternalFormat &GetInternalFormatInfo(GLenum internalFormat) { const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); - InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat); + auto iter = formatMap.find(internalFormat); if (iter != formatMap.end()) { return iter->second; @@ -693,7 +709,14 @@ const InternalFormat &GetInternalFormatInfo(GLenum internalFormat) } } -gl::ErrorOrResult<GLuint> InternalFormat::computeRowPitch(GLenum formatType, +GLuint InternalFormat::computePixelBytes(GLenum formatType) const +{ + const auto &typeInfo = GetTypeInfo(formatType); + GLuint components = typeInfo.specialInterpretation ? 1u : componentCount; + return components * typeInfo.bytes; +} + +ErrorOrResult<GLuint> InternalFormat::computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const @@ -702,24 +725,11 @@ gl::ErrorOrResult<GLuint> InternalFormat::computeRowPitch(GLenum formatType, if (compressed) { ASSERT(rowLength == 0); - return computeCompressedImageSize(formatType, gl::Extents(width, 1, 1)); + return computeCompressedImageSize(formatType, Extents(width, 1, 1)); } - CheckedNumeric<GLuint> checkedRowBytes(0); - if (rowLength > 0) - { - CheckedNumeric<GLuint> checkePixelBytes(pixelBytes); - checkedRowBytes = checkePixelBytes * rowLength; - } - else - { - CheckedNumeric<GLuint> checkedWidth(width); - const auto &typeInfo = GetTypeInfo(formatType); - CheckedNumeric<GLuint> checkedComponents(typeInfo.specialInterpretation ? 1u - : componentCount); - CheckedNumeric<GLuint> checkedTypeBytes(typeInfo.bytes); - checkedRowBytes = checkedWidth * checkedComponents * checkedTypeBytes; - } + CheckedNumeric<GLuint> checkedWidth(rowLength > 0 ? rowLength : width); + CheckedNumeric<GLuint> checkedRowBytes = checkedWidth * computePixelBytes(formatType); ASSERT(alignment > 0 && isPow2(alignment)); CheckedNumeric<GLuint> checkedAlignment(alignment); @@ -728,26 +738,33 @@ gl::ErrorOrResult<GLuint> InternalFormat::computeRowPitch(GLenum formatType, return aligned.ValueOrDie(); } -gl::ErrorOrResult<GLuint> InternalFormat::computeDepthPitch(GLenum formatType, +ErrorOrResult<GLuint> InternalFormat::computeDepthPitch(GLsizei height, + GLint imageHeight, + GLuint rowPitch) const +{ + GLuint rows = + (imageHeight > 0 ? static_cast<GLuint>(imageHeight) : static_cast<GLuint>(height)); + CheckedNumeric<GLuint> checkedRowPitch(rowPitch); + + auto depthPitch = checkedRowPitch * rows; + ANGLE_TRY_CHECKED_MATH(depthPitch); + return depthPitch.ValueOrDie(); +} + +ErrorOrResult<GLuint> InternalFormat::computeDepthPitch(GLenum formatType, GLsizei width, GLsizei height, GLint alignment, GLint rowLength, GLint imageHeight) const { - GLuint rows = - (imageHeight > 0 ? static_cast<GLuint>(imageHeight) : static_cast<GLuint>(height)); GLuint rowPitch = 0; ANGLE_TRY_RESULT(computeRowPitch(formatType, width, alignment, rowLength), rowPitch); - - CheckedNumeric<GLuint> checkedRowPitch(rowPitch); - auto depthPitch = checkedRowPitch * rows; - ANGLE_TRY_CHECKED_MATH(depthPitch); - return depthPitch.ValueOrDie(); + return computeDepthPitch(height, imageHeight, rowPitch); } -gl::ErrorOrResult<GLuint> InternalFormat::computeCompressedImageSize(GLenum formatType, - const gl::Extents &size) const +ErrorOrResult<GLuint> InternalFormat::computeCompressedImageSize(GLenum formatType, + const Extents &size) const { CheckedNumeric<GLuint> checkedWidth(size.width); CheckedNumeric<GLuint> checkedHeight(size.height); @@ -763,21 +780,19 @@ gl::ErrorOrResult<GLuint> InternalFormat::computeCompressedImageSize(GLenum form return bytes.ValueOrDie(); } -gl::ErrorOrResult<GLuint> InternalFormat::computeSkipBytes(GLuint rowPitch, +ErrorOrResult<GLuint> InternalFormat::computeSkipBytes(GLuint rowPitch, GLuint depthPitch, - GLint skipImages, - GLint skipRows, - GLint skipPixels, - bool applySkipImages) const + const PixelStoreStateBase &state, + bool is3D) const { CheckedNumeric<GLuint> checkedRowPitch(rowPitch); CheckedNumeric<GLuint> checkedDepthPitch(depthPitch); - CheckedNumeric<GLuint> checkedSkipImages(static_cast<GLuint>(skipImages)); - CheckedNumeric<GLuint> checkedSkipRows(static_cast<GLuint>(skipRows)); - CheckedNumeric<GLuint> checkedSkipPixels(static_cast<GLuint>(skipPixels)); + CheckedNumeric<GLuint> checkedSkipImages(static_cast<GLuint>(state.skipImages)); + CheckedNumeric<GLuint> checkedSkipRows(static_cast<GLuint>(state.skipRows)); + CheckedNumeric<GLuint> checkedSkipPixels(static_cast<GLuint>(state.skipPixels)); CheckedNumeric<GLuint> checkedPixelBytes(pixelBytes); auto checkedSkipImagesBytes = checkedSkipImages * checkedDepthPitch; - if (!applySkipImages) + if (!is3D) { checkedSkipImagesBytes = 0; } @@ -787,34 +802,49 @@ gl::ErrorOrResult<GLuint> InternalFormat::computeSkipBytes(GLuint rowPitch, return skipBytes.ValueOrDie(); } -gl::ErrorOrResult<GLuint> InternalFormat::computeUnpackSize( +ErrorOrResult<GLuint> InternalFormat::computePackUnpackEndByte( GLenum formatType, - const gl::Extents &size, - const gl::PixelUnpackState &unpack) const + const Extents &size, + const PixelStoreStateBase &state, + bool is3D) const { - // Compressed images do not use unpack parameters. - if (compressed) + GLuint rowPitch = 0; + ANGLE_TRY_RESULT(computeRowPitch(formatType, size.width, state.alignment, state.rowLength), + rowPitch); + + GLuint depthPitch = 0; + if (is3D) { - return computeCompressedImageSize(formatType, size); + ANGLE_TRY_RESULT(computeDepthPitch(size.height, state.imageHeight, rowPitch), depthPitch); } - base::CheckedNumeric<GLuint> checkedGroups(unpack.rowLength > 0 ? unpack.rowLength - : size.width); - base::CheckedNumeric<GLuint> checkedRows(unpack.imageHeight > 0 ? unpack.imageHeight - : size.height); + CheckedNumeric<GLuint> checkedCopyBytes = 0; + if (compressed) + { + ANGLE_TRY_RESULT(computeCompressedImageSize(formatType, size), checkedCopyBytes); + } + else if (size.height != 0 && (!is3D || size.depth != 0)) + { + CheckedNumeric<GLuint> bytes = computePixelBytes(formatType); + checkedCopyBytes += size.width * bytes; - // Compute the groups of all the layers in (0,depth-1) - auto layerGroups = checkedGroups * checkedRows * (size.depth - 1); + CheckedNumeric<GLuint> heightMinusOne = size.height - 1; + checkedCopyBytes += heightMinusOne * rowPitch; - // Compute the groups in the last layer (for non-3D textures, the only one) - auto lastLayerGroups = checkedGroups * (size.height - 1) + size.width; + if (is3D) + { + CheckedNumeric<GLuint> depthMinusOne = size.depth - 1; + checkedCopyBytes += depthMinusOne * depthPitch; + } + } - // The total size is the sum times the bytes per pixel. - auto totalSize = (layerGroups + lastLayerGroups) * pixelBytes; + CheckedNumeric<GLuint> checkedSkipBytes = 0; + ANGLE_TRY_RESULT(computeSkipBytes(rowPitch, depthPitch, state, is3D), checkedSkipBytes); - ANGLE_TRY_CHECKED_MATH(totalSize); + CheckedNumeric<GLuint> endByte = checkedCopyBytes + checkedSkipBytes; - return totalSize.ValueOrDie(); + ANGLE_TRY_CHECKED_MATH(endByte); + return endByte.ValueOrDie(); } GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type) @@ -824,15 +854,7 @@ GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type) { return internalFormat; } - - static const FormatMap formatMap = BuildFormatMap(); - auto iter = formatMap.find(FormatType(internalFormat, type)); - if (iter != formatMap.end()) - { - return iter->second; - } - - return GL_NONE; + return GetSizedFormatInternal(internalFormat, type); } const FormatSet &GetAllSizedInternalFormats() diff --git a/chromium/third_party/angle/src/libANGLE/formatutils.h b/chromium/third_party/angle/src/libANGLE/formatutils.h index b3c02839e5a..5d7e19f61f2 100644 --- a/chromium/third_party/angle/src/libANGLE/formatutils.h +++ b/chromium/third_party/angle/src/libANGLE/formatutils.h @@ -47,27 +47,43 @@ struct InternalFormat { InternalFormat(); - gl::ErrorOrResult<GLuint> computeRowPitch(GLenum formatType, - GLsizei width, - GLint alignment, - GLint rowLength) const; - gl::ErrorOrResult<GLuint> computeDepthPitch(GLenum formatType, - GLsizei width, - GLsizei height, - GLint alignment, - GLint rowLength, - GLint imageHeight) const; - gl::ErrorOrResult<GLuint> computeCompressedImageSize(GLenum formatType, - const gl::Extents &size) const; - gl::ErrorOrResult<GLuint> computeSkipBytes(GLuint rowPitch, - GLuint depthPitch, - GLint skipImages, - GLint skipRows, - GLint skipPixels, - bool applySkipImages) const; - gl::ErrorOrResult<GLuint> computeUnpackSize(GLenum formatType, - const gl::Extents &size, - const gl::PixelUnpackState &unpack) const; + GLuint computePixelBytes(GLenum formatType) const; + + ErrorOrResult<GLuint> computeRowPitch(GLenum formatType, + GLsizei width, + GLint alignment, + GLint rowLength) const; + ErrorOrResult<GLuint> computeDepthPitch(GLsizei height, + GLint imageHeight, + GLuint rowPitch) const; + ErrorOrResult<GLuint> computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight) const; + + ErrorOrResult<GLuint> computeCompressedImageSize(GLenum formatType, + const Extents &size) const; + + ErrorOrResult<GLuint> computeSkipBytes(GLuint rowPitch, + GLuint depthPitch, + const PixelStoreStateBase &state, + bool is3D) const; + + ErrorOrResult<GLuint> computePackUnpackEndByte(GLenum formatType, + const Extents &size, + const PixelStoreStateBase &state, + bool is3D) const; + + bool isLUMA() const; + GLenum getReadPixelsFormat() const; + GLenum getReadPixelsType() const; + + bool operator==(const InternalFormat &other) const; + bool operator!=(const InternalFormat &other) const; + + GLenum internalFormat; GLuint redBits; GLuint greenBits; @@ -101,6 +117,32 @@ struct InternalFormat SupportCheckFunction filterSupport; }; +// A "Format" is either a sized format, or an {unsized format, type} combination. +struct Format +{ + // Sized types only. + explicit Format(GLenum internalFormat); + explicit Format(const InternalFormat &internalFormat); + + // Sized or unsized types. + Format(GLenum internalFormat, GLenum format, GLenum type); + + Format(const Format &other); + Format &operator=(const Format &other); + + GLenum asSized() const; + bool valid() const; + + static Format Invalid(); + static bool SameSized(const Format &a, const Format &b); + + // This is the sized info. + const InternalFormat *info; + GLenum format; + GLenum type; + bool sized; +}; + const InternalFormat &GetInternalFormatInfo(GLenum internalFormat); GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type); @@ -234,7 +276,7 @@ enum VertexFormatType VERTEX_FORMAT_UINT210_INT, }; -typedef std::vector<gl::VertexFormatType> InputLayout; +typedef std::vector<VertexFormatType> InputLayout; struct VertexFormat : angle::NonCopyable { diff --git a/chromium/third_party/angle/src/libANGLE/gen_format_map.py b/chromium/third_party/angle/src/libANGLE/gen_format_map.py new file mode 100644 index 00000000000..5158eae3b5e --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/gen_format_map.py @@ -0,0 +1,90 @@ +#!/usr/bin/python +# Copyright 2016 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# gen_format_map.py: +# Code generation for GL format map. The format map matches between +# {format,type} and internal format. + +from datetime import date +import sys + +sys.path.append('renderer') +import angle_format + +template_cpp = """// GENERATED FILE - DO NOT EDIT. +// Generated by {script_name} using data from {data_source_name}. +// +// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// format_map: +// Determining the sized internal format from a (format,type) pair. + +#include "angle_gl.h" +#include "common/debug.h" + +namespace gl +{{ + +GLenum GetSizedFormatInternal(GLenum format, GLenum type) +{{ + switch (format) + {{ +{format_cases} case GL_NONE: + return GL_NONE; + + default: + break; + }} + + return GL_NONE; +}} + +}} // namespace gl +""" + +template_format_case = """ case {format}: + switch (type) + {{ +{type_cases} default: + break; + }} + break; + +""" + +template_type_case = """ case {type}: + return {internal_format}; +""" + +def parse_type_case(type, internal_format): + return template_type_case.format( + type = type, internal_format = internal_format) + +def parse_format_case(format, type_map): + type_cases = "" + for type, internal_format in sorted(type_map.iteritems()): + type_cases += parse_type_case(type, internal_format) + return template_format_case.format( + format = format, type_cases = type_cases) + +input_script = 'format_map_data.json' + +format_map = angle_format.load_json(input_script) + +format_cases = "" + +for format, type_map in sorted(format_map.iteritems()): + format_cases += parse_format_case(format, type_map) + +with open('format_map_autogen.cpp', 'wt') as out_file: + output_cpp = template_cpp.format( + script_name = sys.argv[0], + data_source_name = input_script, + copyright_year = date.today().year, + format_cases = format_cases) + out_file.write(output_cpp) + out_file.close() diff --git a/chromium/third_party/angle/src/libANGLE/queryconversions.cpp b/chromium/third_party/angle/src/libANGLE/queryconversions.cpp index 3a6059a89cb..611fbc4ba80 100644 --- a/chromium/third_party/angle/src/libANGLE/queryconversions.cpp +++ b/chromium/third_party/angle/src/libANGLE/queryconversions.cpp @@ -86,17 +86,6 @@ QueryT CastStateValue(GLenum pname, NativeT value) } // anonymous namespace -template <> -GLenum GLTypeToGLenum<GLint>::value = GL_INT; -template <> -GLenum GLTypeToGLenum<GLuint>::value = GL_UNSIGNED_INT; -template <> -GLenum GLTypeToGLenum<GLboolean>::value = GL_BOOL; -template <> -GLenum GLTypeToGLenum<GLint64>::value = GL_INT_64_ANGLEX; -template <> -GLenum GLTypeToGLenum<GLfloat>::value = GL_FLOAT; - template <typename QueryT> void CastStateValues(Context *context, GLenum nativeType, GLenum pname, unsigned int numParams, QueryT *outParams) @@ -154,4 +143,77 @@ template void CastStateValues<GLuint>(Context *, GLenum, GLenum, unsigned int, G template void CastStateValues<GLfloat>(Context *, GLenum, GLenum, unsigned int, GLfloat *); template void CastStateValues<GLint64>(Context *, GLenum, GLenum, unsigned int, GLint64 *); +template <typename QueryT> +void CastIndexedStateValues(Context *context, + GLenum nativeType, + GLenum pname, + GLuint index, + unsigned int numParams, + QueryT *outParams) +{ + if (nativeType == GL_INT) + { + std::vector<GLint> intParams(numParams, 0); + context->getIntegeri_v(pname, index, intParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastStateValue<QueryT>(pname, intParams[i]); + } + } + else if (nativeType == GL_BOOL) + { + std::vector<GLboolean> boolParams(numParams, GL_FALSE); + context->getBooleani_v(pname, index, boolParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = + (boolParams[i] == GL_FALSE ? static_cast<QueryT>(0) : static_cast<QueryT>(1)); + } + } + else if (nativeType == GL_INT_64_ANGLEX) + { + std::vector<GLint64> int64Params(numParams, 0); + context->getInteger64i_v(pname, index, int64Params.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastStateValue<QueryT>(pname, int64Params[i]); + } + } + else + UNREACHABLE(); +} + +template void CastIndexedStateValues<GLboolean>(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLboolean *); +template void CastIndexedStateValues<GLint>(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLint *); +template void CastIndexedStateValues<GLuint>(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLuint *); +template void CastIndexedStateValues<GLfloat>(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLfloat *); +template void CastIndexedStateValues<GLint64>(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLint64 *); } diff --git a/chromium/third_party/angle/src/libANGLE/queryconversions.h b/chromium/third_party/angle/src/libANGLE/queryconversions.h index e0fdbe17e0e..5b96a3e1529 100644 --- a/chromium/third_party/angle/src/libANGLE/queryconversions.h +++ b/chromium/third_party/angle/src/libANGLE/queryconversions.h @@ -23,7 +23,33 @@ class Context; template <typename GLType> struct GLTypeToGLenum { - static GLenum value; + // static constexpr GLenum value; +}; + +template <> +struct GLTypeToGLenum<GLint> +{ + static constexpr GLenum value = GL_INT; +}; +template <> +struct GLTypeToGLenum<GLuint> +{ + static constexpr GLenum value = GL_UNSIGNED_INT; +}; +template <> +struct GLTypeToGLenum<GLboolean> +{ + static constexpr GLenum value = GL_BOOL; +}; +template <> +struct GLTypeToGLenum<GLint64> +{ + static constexpr GLenum value = GL_INT_64_ANGLEX; +}; +template <> +struct GLTypeToGLenum<GLfloat> +{ + static constexpr GLenum value = GL_FLOAT; }; // The GL state query API types are: bool, int, uint, float, int64 @@ -31,6 +57,14 @@ template <typename QueryT> void CastStateValues(Context *context, GLenum nativeType, GLenum pname, unsigned int numParams, QueryT *outParams); +// The GL state query API types are: bool, int, uint, float, int64 +template <typename QueryT> +void CastIndexedStateValues(Context *context, + GLenum nativeType, + GLenum pname, + GLuint index, + unsigned int numParams, + QueryT *outParams); } #endif // LIBANGLE_QUERY_CONVERSIONS_H_ diff --git a/chromium/third_party/angle/src/libANGLE/queryutils.cpp b/chromium/third_party/angle/src/libANGLE/queryutils.cpp new file mode 100644 index 00000000000..3fdd91ad7b9 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/queryutils.cpp @@ -0,0 +1,204 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryutils.cpp: Utilities for querying values from GL objects + +#include "libANGLE/queryutils.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Program.h" + +namespace gl +{ +void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, + GLenum attachment, + GLenum pname, + GLint *params) +{ + ASSERT(framebuffer); + + const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment); + if (attachmentObject == nullptr) + { + // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + // is NONE, then querying any other pname will generate INVALID_ENUM. + + // ES 3.0.2 spec pg 235 states that if the attachment type is none, + // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an + // INVALID_OPERATION for all other pnames + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = GL_NONE; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + *params = 0; + break; + + default: + UNREACHABLE(); + break; + } + + return; + } + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = attachmentObject->type(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + *params = attachmentObject->id(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + *params = attachmentObject->mipLevel(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + *params = attachmentObject->cubeMapFace(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + *params = attachmentObject->getRedSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + *params = attachmentObject->getGreenSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + *params = attachmentObject->getBlueSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + *params = attachmentObject->getAlphaSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + *params = attachmentObject->getDepthSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + *params = attachmentObject->getStencilSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + *params = attachmentObject->getComponentType(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + *params = attachmentObject->getColorEncoding(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + *params = attachmentObject->layer(); + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params) +{ + ASSERT(buffer != nullptr); + + switch (pname) + { + case GL_BUFFER_USAGE: + *params = static_cast<GLint>(buffer->getUsage()); + break; + case GL_BUFFER_SIZE: + *params = clampCast<GLint>(buffer->getSize()); + break; + case GL_BUFFER_ACCESS_FLAGS: + *params = buffer->getAccessFlags(); + break; + case GL_BUFFER_ACCESS_OES: + *params = buffer->getAccess(); + break; + case GL_BUFFER_MAPPED: + *params = static_cast<GLint>(buffer->isMapped()); + break; + case GL_BUFFER_MAP_OFFSET: + *params = clampCast<GLint>(buffer->getMapOffset()); + break; + case GL_BUFFER_MAP_LENGTH: + *params = clampCast<GLint>(buffer->getMapLength()); + break; + default: + UNREACHABLE(); + break; + } +} + +void QueryProgramiv(const Program *program, GLenum pname, GLint *params) +{ + ASSERT(program != nullptr); + + switch (pname) + { + case GL_DELETE_STATUS: + *params = program->isFlaggedForDeletion(); + return; + case GL_LINK_STATUS: + *params = program->isLinked(); + return; + case GL_VALIDATE_STATUS: + *params = program->isValidated(); + return; + case GL_INFO_LOG_LENGTH: + *params = program->getInfoLogLength(); + return; + case GL_ATTACHED_SHADERS: + *params = program->getAttachedShadersCount(); + return; + case GL_ACTIVE_ATTRIBUTES: + *params = program->getActiveAttributeCount(); + return; + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + *params = program->getActiveAttributeMaxLength(); + return; + case GL_ACTIVE_UNIFORMS: + *params = program->getActiveUniformCount(); + return; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + *params = program->getActiveUniformMaxLength(); + return; + case GL_PROGRAM_BINARY_LENGTH_OES: + *params = program->getBinaryLength(); + return; + case GL_ACTIVE_UNIFORM_BLOCKS: + *params = program->getActiveUniformBlockCount(); + return; + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + *params = program->getActiveUniformBlockMaxLength(); + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + *params = program->getTransformFeedbackBufferMode(); + break; + case GL_TRANSFORM_FEEDBACK_VARYINGS: + *params = program->getTransformFeedbackVaryingCount(); + break; + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + *params = program->getTransformFeedbackVaryingMaxLength(); + break; + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + *params = program->getBinaryRetrievableHint(); + break; + default: + UNREACHABLE(); + break; + } +} +} diff --git a/chromium/third_party/angle/src/libANGLE/queryutils.h b/chromium/third_party/angle/src/libANGLE/queryutils.h new file mode 100644 index 00000000000..2ca4d66d4b2 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/queryutils.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryutils.h: Utilities for querying values from GL objects + +#ifndef LIBANGLE_QUERYUTILS_H_ +#define LIBANGLE_QUERYUTILS_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" + +namespace gl +{ +class Buffer; +class Framebuffer; +class Program; + +void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, + GLenum attachment, + GLenum pname, + GLint *params); +void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params); +void QueryProgramiv(const Program *program, GLenum pname, GLint *params); +} + +#endif // LIBANGLE_QUERYUTILS_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl.h index cdb3cfe884c..8904bf31ebe 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl.h @@ -23,8 +23,8 @@ class BufferImpl : angle::NonCopyable public: virtual ~BufferImpl() { } - virtual gl::Error setData(const void *data, size_t size, GLenum usage) = 0; - virtual gl::Error setSubData(const void *data, size_t size, size_t offset) = 0; + virtual gl::Error setData(GLenum target, const void *data, size_t size, GLenum usage) = 0; + virtual gl::Error setSubData(GLenum target, const void *data, size_t size, size_t offset) = 0; virtual gl::Error copySubData(BufferImpl *source, GLintptr sourceOffset, GLintptr destOffset, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl_mock.h b/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl_mock.h index a6387661cea..46e07b47081 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl_mock.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/BufferImpl_mock.h @@ -21,8 +21,8 @@ class MockBufferImpl : public BufferImpl public: ~MockBufferImpl() { destructor(); } - MOCK_METHOD3(setData, gl::Error(const void*, size_t, GLenum)); - MOCK_METHOD3(setSubData, gl::Error(const void*, size_t, size_t)); + MOCK_METHOD4(setData, gl::Error(GLenum, const void *, size_t, GLenum)); + MOCK_METHOD4(setSubData, gl::Error(GLenum, const void *, size_t, size_t)); MOCK_METHOD4(copySubData, gl::Error(BufferImpl *, GLintptr, GLintptr, GLsizeiptr)); MOCK_METHOD2(map, gl::Error(GLenum, GLvoid **)); MOCK_METHOD4(mapRange, gl::Error(size_t, size_t, GLbitfield, GLvoid **)); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.cpp b/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.cpp index c08ab5a57bc..0e1c9ff41e7 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.cpp @@ -56,4 +56,58 @@ void ContextImpl::stencilThenCoverStrokePath(const gl::Path *path, UNREACHABLE(); } +void ContextImpl::coverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::coverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilThenCoverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilThenCoverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.h index 7283b95ede4..3fc9db59373 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/ContextImpl.h @@ -10,6 +10,8 @@ #ifndef LIBANGLE_RENDERER_CONTEXTIMPL_H_ #define LIBANGLE_RENDERER_CONTEXTIMPL_H_ +#include <vector> + #include "common/angleutils.h" #include "libANGLE/ContextState.h" #include "libANGLE/renderer/GLImplFactory.h" @@ -74,11 +76,39 @@ class ContextImpl : public GLImplFactory GLuint mask, GLenum coverMode); - // TODO(jmadill): Investigate proper impl methods for this. - virtual void notifyDeviceLost() = 0; - virtual bool isDeviceLost() const = 0; - virtual bool testDeviceLost() = 0; - virtual bool testDeviceResettable() = 0; + virtual void coverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + virtual void coverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilThenCoverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilThenCoverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + + // Device loss + virtual GLenum getResetStatus() = 0; // Vendor and description strings. virtual std::string getVendorString() const = 0; @@ -106,7 +136,8 @@ class ContextImpl : public GLImplFactory virtual const gl::Limitations &getNativeLimitations() const = 0; const gl::ContextState &getContextState() { return mState; } - int getClientVersion() const { return mState.getClientVersion(); } + int getClientMajorVersion() const { return mState.getClientMajorVersion(); } + int getClientMinorVersion() const { return mState.getClientMinorVersion(); } const gl::State &getGLState() const { return mState.getState(); } const gl::Caps &getCaps() const { return mState.getCaps(); } const gl::TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/DisplayImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/DisplayImpl.h index 8b5a80d9edf..652486edbd8 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/DisplayImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/DisplayImpl.h @@ -15,6 +15,7 @@ #include "libANGLE/Error.h" #include "libANGLE/renderer/EGLImplFactory.h" #include "libANGLE/Stream.h" +#include "libANGLE/Version.h" #include <set> #include <vector> @@ -54,7 +55,6 @@ class DisplayImpl : public EGLImplFactory virtual egl::ConfigSet generateConfigs() = 0; - virtual bool isDeviceLost() const = 0; virtual bool testDeviceLost() = 0; virtual egl::Error restoreLostDevice() = 0; @@ -68,7 +68,7 @@ class DisplayImpl : public EGLImplFactory virtual egl::Error waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const = 0; - + virtual gl::Version getMaxSupportedESVersion() const = 0; const egl::Caps &getCaps() const; typedef std::set<egl::Surface*> SurfaceSet; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/Format.cpp b/chromium/third_party/angle/src/libANGLE/renderer/Format.cpp new file mode 100644 index 00000000000..8e4a0e725ea --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/Format.cpp @@ -0,0 +1,72 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Format: +// A universal description of texture storage. Across multiple +// renderer back-ends, there are common formats and some distinct +// permutations, this enum encapsulates them all. + +#include "libANGLE/renderer/Format.h" + +#include "image_util/copyimage.h" + +using namespace rx; + +namespace angle +{ + +namespace +{ + +const FastCopyFunctionMap &GetFastCopyFunctionsMap(Format::ID formatID) +{ + switch (formatID) + { + case Format::ID::B8G8R8A8_UNORM: + { + static FastCopyFunctionMap fastCopyMap; + if (fastCopyMap.empty()) + { + fastCopyMap[gl::FormatType(GL_RGBA, GL_UNSIGNED_BYTE)] = CopyBGRA8ToRGBA8; + } + return fastCopyMap; + } + default: + { + static FastCopyFunctionMap emptyMap; + return emptyMap; + } + } +} + +} // anonymous namespace + +Format::Format(ID id, + GLenum glFormat, + GLenum fboFormat, + MipGenerationFunction mipGen, + ColorReadFunction colorRead, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint depthBits, + GLuint stencilBits) + : id(id), + glInternalFormat(glFormat), + fboImplementationInternalFormat(fboFormat), + mipGenerationFunction(mipGen), + colorReadFunction(colorRead), + fastCopyFunctions(GetFastCopyFunctionsMap(id)), + redBits(redBits), + greenBits(greenBits), + blueBits(blueBits), + alphaBits(alphaBits), + depthBits(depthBits), + stencilBits(stencilBits) +{ +} + +} // namespace angle diff --git a/chromium/third_party/angle/src/libANGLE/renderer/Format.h b/chromium/third_party/angle/src/libANGLE/renderer/Format.h new file mode 100644 index 00000000000..c954c9246b2 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/Format.h @@ -0,0 +1,68 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Format: +// A universal description of typed GPU storage. Across multiple +// renderer back-ends, there are common formats and some distinct +// permutations, this enum encapsulates them all. Formats apply to +// textures, but could also apply to any typed data. + +#ifndef LIBANGLE_RENDERER_FORMAT_H_ +#define LIBANGLE_RENDERER_FORMAT_H_ + +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace angle +{ + +struct Format final : angle::NonCopyable +{ + enum class ID; + + Format(ID id, + GLenum glFormat, + GLenum fboFormat, + rx::MipGenerationFunction mipGen, + rx::ColorReadFunction colorRead, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint depthBits, + GLuint stencilBits); + + static const Format &Get(ID id); + + ID id; + + // The closest matching GL internal format for the storage this format uses. Note that this + // may be a different internal format than the one this ANGLE format is used for. + GLenum glInternalFormat; + + // The format we should report to the GL layer when querying implementation formats from a FBO. + // This might not be the same as the glInternalFormat, since some DXGI formats don't have + // matching GL format enums, like BGRA4, BGR5A1 and B5G6R6. + GLenum fboImplementationInternalFormat; + + rx::MipGenerationFunction mipGenerationFunction; + rx::ColorReadFunction colorReadFunction; + + // A map from a gl::FormatType to a fast pixel copy function for this format. + rx::FastCopyFunctionMap fastCopyFunctions; + + GLuint redBits; + GLuint greenBits; + GLuint blueBits; + GLuint alphaBits; + GLuint depthBits; + GLuint stencilBits; +}; + +} // namespace angle + +#include "libANGLE/renderer/Format_ID_autogen.inl" + +#endif // LIBANGLE_RENDERER_FORMAT_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/Format_ID_autogen.inl b/chromium/third_party/angle/src/libANGLE/renderer/Format_ID_autogen.inl new file mode 100644 index 00000000000..deee1fea100 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/Format_ID_autogen.inl @@ -0,0 +1,138 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE format enumeration. + +namespace angle +{ + +enum class Format::ID +{ + NONE, + A16_FLOAT, + A32_FLOAT, + A8_UNORM, + ASTC_10x10_SRGB_BLOCK, + ASTC_10x10_UNORM_BLOCK, + ASTC_10x5_SRGB_BLOCK, + ASTC_10x5_UNORM_BLOCK, + ASTC_10x6_SRGB_BLOCK, + ASTC_10x6_UNORM_BLOCK, + ASTC_10x8_SRGB_BLOCK, + ASTC_10x8_UNORM_BLOCK, + ASTC_12x10_SRGB_BLOCK, + ASTC_12x10_UNORM_BLOCK, + ASTC_12x12_SRGB_BLOCK, + ASTC_12x12_UNORM_BLOCK, + ASTC_4x4_SRGB_BLOCK, + ASTC_4x4_UNORM_BLOCK, + ASTC_5x4_SRGB_BLOCK, + ASTC_5x4_UNORM_BLOCK, + ASTC_5x5_SRGB_BLOCK, + ASTC_5x5_UNORM_BLOCK, + ASTC_6x5_SRGB_BLOCK, + ASTC_6x5_UNORM_BLOCK, + ASTC_6x6_SRGB_BLOCK, + ASTC_6x6_UNORM_BLOCK, + ASTC_8x5_SRGB_BLOCK, + ASTC_8x5_UNORM_BLOCK, + ASTC_8x6_SRGB_BLOCK, + ASTC_8x6_UNORM_BLOCK, + ASTC_8x8_SRGB_BLOCK, + ASTC_8x8_UNORM_BLOCK, + B4G4R4A4_UNORM, + B5G5R5A1_UNORM, + B5G6R5_UNORM, + B8G8R8A8_UNORM, + B8G8R8X8_UNORM, + BC1_RGBA_UNORM_BLOCK, + BC1_RGB_UNORM_BLOCK, + BC2_RGBA_UNORM_BLOCK, + BC3_RGBA_UNORM_BLOCK, + D16_UNORM, + D24_UNORM, + D24_UNORM_S8_UINT, + D32_FLOAT, + D32_FLOAT_S8X24_UINT, + D32_UNORM, + EAC_R11G11_SNORM_BLOCK, + EAC_R11G11_UNORM_BLOCK, + EAC_R11_SNORM_BLOCK, + EAC_R11_UNORM_BLOCK, + ETC2_R8G8B8A1_SRGB_BLOCK, + ETC2_R8G8B8A1_UNORM_BLOCK, + ETC2_R8G8B8A8_SRGB_BLOCK, + ETC2_R8G8B8A8_UNORM_BLOCK, + ETC2_R8G8B8_SRGB_BLOCK, + ETC2_R8G8B8_UNORM_BLOCK, + L16A16_FLOAT, + L16_FLOAT, + L32A32_FLOAT, + L32_FLOAT, + L8A8_UNORM, + L8_UNORM, + R10G10B10A2_UINT, + R10G10B10A2_UNORM, + R11G11B10_FLOAT, + R16G16B16A16_FLOAT, + R16G16B16A16_SINT, + R16G16B16A16_SNORM, + R16G16B16A16_UINT, + R16G16B16A16_UNORM, + R16G16B16_FLOAT, + R16G16B16_SINT, + R16G16B16_SNORM, + R16G16B16_UINT, + R16G16B16_UNORM, + R16G16_FLOAT, + R16G16_SINT, + R16G16_SNORM, + R16G16_UINT, + R16G16_UNORM, + R16_FLOAT, + R16_SINT, + R16_SNORM, + R16_UINT, + R16_UNORM, + R32G32B32A32_FLOAT, + R32G32B32A32_SINT, + R32G32B32A32_UINT, + R32G32B32_FLOAT, + R32G32B32_SINT, + R32G32B32_UINT, + R32G32_FLOAT, + R32G32_SINT, + R32G32_UINT, + R32_FLOAT, + R32_SINT, + R32_UINT, + R4G4B4A4_UNORM, + R5G5B5A1_UNORM, + R5G6B5_UNORM, + R8G8B8A8_SINT, + R8G8B8A8_SNORM, + R8G8B8A8_UINT, + R8G8B8A8_UNORM, + R8G8B8A8_UNORM_SRGB, + R8G8B8_SINT, + R8G8B8_SNORM, + R8G8B8_UINT, + R8G8B8_UNORM, + R8G8B8_UNORM_SRGB, + R8G8_SINT, + R8G8_SNORM, + R8G8_UINT, + R8G8_UNORM, + R8_SINT, + R8_SNORM, + R8_UINT, + R8_UNORM, + R9G9B9E5_SHAREDEXP, + S8_UINT +}; + +} // namespace angle diff --git a/chromium/third_party/angle/src/libANGLE/renderer/Format_autogen.cpp b/chromium/third_party/angle/src/libANGLE/renderer/Format_autogen.cpp new file mode 100644 index 00000000000..791a1b068d9 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/Format_autogen.cpp @@ -0,0 +1,1247 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE Format table: +// Queries for typed format information from the ANGLE format enum. + +#include "libANGLE/renderer/Format.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +namespace angle +{ + +// static +const Format &Format::Get(ID id) +{ + // clang-format off + switch (id) + { + case ID::A16_FLOAT: + { + static const Format info(ID::A16_FLOAT, + GL_ALPHA16F_EXT, + GL_ALPHA16F_EXT, + GenerateMip<A16F>, + ReadColor<A16F, GLfloat>, + 0, 0, 0, 16, 0, 0); + return info; + } + case ID::A32_FLOAT: + { + static const Format info(ID::A32_FLOAT, + GL_ALPHA32F_EXT, + GL_ALPHA32F_EXT, + GenerateMip<A32F>, + ReadColor<A32F, GLfloat>, + 0, 0, 0, 32, 0, 0); + return info; + } + case ID::A8_UNORM: + { + static const Format info(ID::A8_UNORM, + GL_ALPHA8_EXT, + GL_ALPHA8_EXT, + GenerateMip<A8>, + ReadColor<A8, GLfloat>, + 0, 0, 0, 8, 0, 0); + return info; + } + case ID::ASTC_10x10_SRGB_BLOCK: + { + static const Format info(ID::ASTC_10x10_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_10x10_UNORM_BLOCK: + { + static const Format info(ID::ASTC_10x10_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_10x10_KHR, + GL_COMPRESSED_RGBA_ASTC_10x10_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_10x5_SRGB_BLOCK: + { + static const Format info(ID::ASTC_10x5_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_10x5_UNORM_BLOCK: + { + static const Format info(ID::ASTC_10x5_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_10x5_KHR, + GL_COMPRESSED_RGBA_ASTC_10x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_10x6_SRGB_BLOCK: + { + static const Format info(ID::ASTC_10x6_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_10x6_UNORM_BLOCK: + { + static const Format info(ID::ASTC_10x6_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_10x6_KHR, + GL_COMPRESSED_RGBA_ASTC_10x6_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_10x8_SRGB_BLOCK: + { + static const Format info(ID::ASTC_10x8_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_10x8_UNORM_BLOCK: + { + static const Format info(ID::ASTC_10x8_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_10x8_KHR, + GL_COMPRESSED_RGBA_ASTC_10x8_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_12x10_SRGB_BLOCK: + { + static const Format info(ID::ASTC_12x10_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_12x10_UNORM_BLOCK: + { + static const Format info(ID::ASTC_12x10_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_12x10_KHR, + GL_COMPRESSED_RGBA_ASTC_12x10_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_12x12_SRGB_BLOCK: + { + static const Format info(ID::ASTC_12x12_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_12x12_UNORM_BLOCK: + { + static const Format info(ID::ASTC_12x12_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_12x12_KHR, + GL_COMPRESSED_RGBA_ASTC_12x12_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_4x4_SRGB_BLOCK: + { + static const Format info(ID::ASTC_4x4_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_4x4_UNORM_BLOCK: + { + static const Format info(ID::ASTC_4x4_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_4x4_KHR, + GL_COMPRESSED_RGBA_ASTC_4x4_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_5x4_SRGB_BLOCK: + { + static const Format info(ID::ASTC_5x4_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_5x4_UNORM_BLOCK: + { + static const Format info(ID::ASTC_5x4_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_5x4_KHR, + GL_COMPRESSED_RGBA_ASTC_5x4_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_5x5_SRGB_BLOCK: + { + static const Format info(ID::ASTC_5x5_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_5x5_UNORM_BLOCK: + { + static const Format info(ID::ASTC_5x5_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_5x5_KHR, + GL_COMPRESSED_RGBA_ASTC_5x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_6x5_SRGB_BLOCK: + { + static const Format info(ID::ASTC_6x5_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_6x5_UNORM_BLOCK: + { + static const Format info(ID::ASTC_6x5_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_6x5_KHR, + GL_COMPRESSED_RGBA_ASTC_6x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_6x6_SRGB_BLOCK: + { + static const Format info(ID::ASTC_6x6_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_6x6_UNORM_BLOCK: + { + static const Format info(ID::ASTC_6x6_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_6x6_KHR, + GL_COMPRESSED_RGBA_ASTC_6x6_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_8x5_SRGB_BLOCK: + { + static const Format info(ID::ASTC_8x5_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_8x5_UNORM_BLOCK: + { + static const Format info(ID::ASTC_8x5_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_8x5_KHR, + GL_COMPRESSED_RGBA_ASTC_8x5_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_8x6_SRGB_BLOCK: + { + static const Format info(ID::ASTC_8x6_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_8x6_UNORM_BLOCK: + { + static const Format info(ID::ASTC_8x6_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_8x6_KHR, + GL_COMPRESSED_RGBA_ASTC_8x6_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_8x8_SRGB_BLOCK: + { + static const Format info(ID::ASTC_8x8_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::ASTC_8x8_UNORM_BLOCK: + { + static const Format info(ID::ASTC_8x8_UNORM_BLOCK, + GL_COMPRESSED_RGBA_ASTC_8x8_KHR, + GL_COMPRESSED_RGBA_ASTC_8x8_KHR, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::B4G4R4A4_UNORM: + { + static const Format info(ID::B4G4R4A4_UNORM, + GL_BGRA4_ANGLEX, + GL_RGBA4, + GenerateMip<A4R4G4B4>, + ReadColor<A4R4G4B4, GLfloat>, + 4, 4, 4, 4, 0, 0); + return info; + } + case ID::B5G5R5A1_UNORM: + { + static const Format info(ID::B5G5R5A1_UNORM, + GL_BGR5_A1_ANGLEX, + GL_RGB5_A1, + GenerateMip<A1R5G5B5>, + ReadColor<A1R5G5B5, GLfloat>, + 5, 5, 5, 1, 0, 0); + return info; + } + case ID::B5G6R5_UNORM: + { + static const Format info(ID::B5G6R5_UNORM, + GL_BGR565_ANGLEX, + GL_RGB565, + GenerateMip<B5G6R5>, + ReadColor<B5G6R5, GLfloat>, + 5, 6, 5, 0, 0, 0); + return info; + } + case ID::B8G8R8A8_UNORM: + { + static const Format info(ID::B8G8R8A8_UNORM, + GL_BGRA8_EXT, + GL_BGRA8_EXT, + GenerateMip<B8G8R8A8>, + ReadColor<B8G8R8A8, GLfloat>, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::B8G8R8X8_UNORM: + { + static const Format info(ID::B8G8R8X8_UNORM, + GL_BGRA8_EXT, + GL_BGRA8_EXT, + GenerateMip<B8G8R8X8>, + ReadColor<B8G8R8X8, GLfloat>, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::BC1_RGBA_UNORM_BLOCK: + { + static const Format info(ID::BC1_RGBA_UNORM_BLOCK, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::BC1_RGB_UNORM_BLOCK: + { + static const Format info(ID::BC1_RGB_UNORM_BLOCK, + GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::BC2_RGBA_UNORM_BLOCK: + { + static const Format info(ID::BC2_RGBA_UNORM_BLOCK, + GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::BC3_RGBA_UNORM_BLOCK: + { + static const Format info(ID::BC3_RGBA_UNORM_BLOCK, + GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::D16_UNORM: + { + static const Format info(ID::D16_UNORM, + GL_DEPTH_COMPONENT16, + GL_DEPTH_COMPONENT16, + nullptr, + nullptr, + 0, 0, 0, 0, 16, 0); + return info; + } + case ID::D24_UNORM: + { + static const Format info(ID::D24_UNORM, + GL_DEPTH_COMPONENT24, + GL_DEPTH_COMPONENT24, + nullptr, + nullptr, + 0, 0, 0, 0, 24, 0); + return info; + } + case ID::D24_UNORM_S8_UINT: + { + static const Format info(ID::D24_UNORM_S8_UINT, + GL_DEPTH24_STENCIL8, + GL_DEPTH24_STENCIL8, + nullptr, + nullptr, + 0, 0, 0, 0, 24, 8); + return info; + } + case ID::D32_FLOAT: + { + static const Format info(ID::D32_FLOAT, + GL_DEPTH_COMPONENT32F, + GL_DEPTH_COMPONENT32F, + nullptr, + nullptr, + 0, 0, 0, 0, 32, 0); + return info; + } + case ID::D32_FLOAT_S8X24_UINT: + { + static const Format info(ID::D32_FLOAT_S8X24_UINT, + GL_DEPTH32F_STENCIL8, + GL_DEPTH32F_STENCIL8, + nullptr, + nullptr, + 0, 0, 0, 0, 32, 8); + return info; + } + case ID::D32_UNORM: + { + static const Format info(ID::D32_UNORM, + GL_DEPTH_COMPONENT32_OES, + GL_DEPTH_COMPONENT32_OES, + nullptr, + nullptr, + 0, 0, 0, 0, 32, 0); + return info; + } + case ID::EAC_R11G11_SNORM_BLOCK: + { + static const Format info(ID::EAC_R11G11_SNORM_BLOCK, + GL_COMPRESSED_SIGNED_RG11_EAC, + GL_COMPRESSED_SIGNED_RG11_EAC, + nullptr, + nullptr, + 11, 11, 0, 0, 0, 0); + return info; + } + case ID::EAC_R11G11_UNORM_BLOCK: + { + static const Format info(ID::EAC_R11G11_UNORM_BLOCK, + GL_COMPRESSED_RG11_EAC, + GL_COMPRESSED_RG11_EAC, + nullptr, + nullptr, + 11, 11, 0, 0, 0, 0); + return info; + } + case ID::EAC_R11_SNORM_BLOCK: + { + static const Format info(ID::EAC_R11_SNORM_BLOCK, + GL_COMPRESSED_SIGNED_R11_EAC, + GL_COMPRESSED_SIGNED_R11_EAC, + nullptr, + nullptr, + 11, 0, 0, 0, 0, 0); + return info; + } + case ID::EAC_R11_UNORM_BLOCK: + { + static const Format info(ID::EAC_R11_UNORM_BLOCK, + GL_COMPRESSED_R11_EAC, + GL_COMPRESSED_R11_EAC, + nullptr, + nullptr, + 11, 0, 0, 0, 0, 0); + return info; + } + case ID::ETC2_R8G8B8A1_SRGB_BLOCK: + { + static const Format info(ID::ETC2_R8G8B8A1_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + nullptr, + nullptr, + 8, 8, 8, 1, 0, 0); + return info; + } + case ID::ETC2_R8G8B8A1_UNORM_BLOCK: + { + static const Format info(ID::ETC2_R8G8B8A1_UNORM_BLOCK, + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + nullptr, + nullptr, + 8, 8, 8, 1, 0, 0); + return info; + } + case ID::ETC2_R8G8B8A8_SRGB_BLOCK: + { + static const Format info(ID::ETC2_R8G8B8A8_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + nullptr, + nullptr, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::ETC2_R8G8B8A8_UNORM_BLOCK: + { + static const Format info(ID::ETC2_R8G8B8A8_UNORM_BLOCK, + GL_COMPRESSED_RGBA8_ETC2_EAC, + GL_COMPRESSED_RGBA8_ETC2_EAC, + nullptr, + nullptr, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::ETC2_R8G8B8_SRGB_BLOCK: + { + static const Format info(ID::ETC2_R8G8B8_SRGB_BLOCK, + GL_COMPRESSED_SRGB8_ETC2, + GL_COMPRESSED_SRGB8_ETC2, + nullptr, + nullptr, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::ETC2_R8G8B8_UNORM_BLOCK: + { + static const Format info(ID::ETC2_R8G8B8_UNORM_BLOCK, + GL_COMPRESSED_RGB8_ETC2, + GL_COMPRESSED_RGB8_ETC2, + nullptr, + nullptr, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::L16A16_FLOAT: + { + static const Format info(ID::L16A16_FLOAT, + GL_LUMINANCE_ALPHA16F_EXT, + GL_LUMINANCE_ALPHA16F_EXT, + GenerateMip<L16A16F>, + ReadColor<L16A16F, GLfloat>, + 0, 0, 0, 16, 0, 0); + return info; + } + case ID::L16_FLOAT: + { + static const Format info(ID::L16_FLOAT, + GL_LUMINANCE16F_EXT, + GL_LUMINANCE16F_EXT, + GenerateMip<L16F>, + ReadColor<L16F, GLfloat>, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::L32A32_FLOAT: + { + static const Format info(ID::L32A32_FLOAT, + GL_LUMINANCE_ALPHA32F_EXT, + GL_LUMINANCE_ALPHA32F_EXT, + GenerateMip<L32A32F>, + ReadColor<L32A32F, GLfloat>, + 0, 0, 0, 32, 0, 0); + return info; + } + case ID::L32_FLOAT: + { + static const Format info(ID::L32_FLOAT, + GL_LUMINANCE32F_EXT, + GL_LUMINANCE32F_EXT, + GenerateMip<L32F>, + ReadColor<L32F, GLfloat>, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::L8A8_UNORM: + { + static const Format info(ID::L8A8_UNORM, + GL_LUMINANCE8_ALPHA8_EXT, + GL_LUMINANCE8_ALPHA8_EXT, + GenerateMip<L8A8>, + ReadColor<L8A8, GLfloat>, + 0, 0, 0, 8, 0, 0); + return info; + } + case ID::L8_UNORM: + { + static const Format info(ID::L8_UNORM, + GL_LUMINANCE8_EXT, + GL_LUMINANCE8_EXT, + GenerateMip<L8>, + ReadColor<L8, GLfloat>, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::NONE: + { + static const Format info(ID::NONE, + GL_NONE, + GL_NONE, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 0); + return info; + } + case ID::R10G10B10A2_UINT: + { + static const Format info(ID::R10G10B10A2_UINT, + GL_RGB10_A2UI, + GL_RGB10_A2UI, + GenerateMip<R10G10B10A2>, + ReadColor<R10G10B10A2, GLuint>, + 10, 10, 10, 2, 0, 0); + return info; + } + case ID::R10G10B10A2_UNORM: + { + static const Format info(ID::R10G10B10A2_UNORM, + GL_RGB10_A2, + GL_RGB10_A2, + GenerateMip<R10G10B10A2>, + ReadColor<R10G10B10A2, GLfloat>, + 10, 10, 10, 2, 0, 0); + return info; + } + case ID::R11G11B10_FLOAT: + { + static const Format info(ID::R11G11B10_FLOAT, + GL_R11F_G11F_B10F, + GL_R11F_G11F_B10F, + GenerateMip<R11G11B10F>, + ReadColor<R11G11B10F, GLfloat>, + 11, 11, 10, 0, 0, 0); + return info; + } + case ID::R16G16B16A16_FLOAT: + { + static const Format info(ID::R16G16B16A16_FLOAT, + GL_RGBA16F, + GL_RGBA16F, + GenerateMip<R16G16B16A16F>, + ReadColor<R16G16B16A16F, GLfloat>, + 16, 16, 16, 16, 0, 0); + return info; + } + case ID::R16G16B16A16_SINT: + { + static const Format info(ID::R16G16B16A16_SINT, + GL_RGBA16I, + GL_RGBA16I, + GenerateMip<R16G16B16A16S>, + ReadColor<R16G16B16A16S, GLint>, + 16, 16, 16, 16, 0, 0); + return info; + } + case ID::R16G16B16A16_SNORM: + { + static const Format info(ID::R16G16B16A16_SNORM, + GL_RGBA16_SNORM_EXT, + GL_RGBA16_SNORM_EXT, + GenerateMip<R16G16B16A16S>, + ReadColor<R16G16B16A16S, GLfloat>, + 16, 16, 16, 16, 0, 0); + return info; + } + case ID::R16G16B16A16_UINT: + { + static const Format info(ID::R16G16B16A16_UINT, + GL_RGBA16UI, + GL_RGBA16UI, + GenerateMip<R16G16B16A16>, + ReadColor<R16G16B16A16, GLuint>, + 16, 16, 16, 16, 0, 0); + return info; + } + case ID::R16G16B16A16_UNORM: + { + static const Format info(ID::R16G16B16A16_UNORM, + GL_RGBA16_EXT, + GL_RGBA16_EXT, + GenerateMip<R16G16B16A16>, + ReadColor<R16G16B16A16, GLfloat>, + 16, 16, 16, 16, 0, 0); + return info; + } + case ID::R16G16B16_FLOAT: + { + static const Format info(ID::R16G16B16_FLOAT, + GL_RGB16F, + GL_RGB16F, + GenerateMip<R16G16B16F>, + ReadColor<R16G16B16F, GLfloat>, + 16, 16, 16, 0, 0, 0); + return info; + } + case ID::R16G16B16_SINT: + { + static const Format info(ID::R16G16B16_SINT, + GL_RGB16I, + GL_RGB16I, + GenerateMip<R16G16B16S>, + ReadColor<R16G16B16S, GLint>, + 16, 16, 16, 0, 0, 0); + return info; + } + case ID::R16G16B16_SNORM: + { + static const Format info(ID::R16G16B16_SNORM, + GL_RGB16_SNORM_EXT, + GL_RGB16_SNORM_EXT, + GenerateMip<R16G16B16S>, + ReadColor<R16G16B16S, GLfloat>, + 16, 16, 16, 0, 0, 0); + return info; + } + case ID::R16G16B16_UINT: + { + static const Format info(ID::R16G16B16_UINT, + GL_RGB16UI, + GL_RGB16UI, + GenerateMip<R16G16B16>, + ReadColor<R16G16B16, GLuint>, + 16, 16, 16, 0, 0, 0); + return info; + } + case ID::R16G16B16_UNORM: + { + static const Format info(ID::R16G16B16_UNORM, + GL_RGB16_EXT, + GL_RGB16_EXT, + GenerateMip<R16G16B16>, + ReadColor<R16G16B16, GLfloat>, + 16, 16, 16, 0, 0, 0); + return info; + } + case ID::R16G16_FLOAT: + { + static const Format info(ID::R16G16_FLOAT, + GL_RG16F, + GL_RG16F, + GenerateMip<R16G16F>, + ReadColor<R16G16F, GLfloat>, + 16, 16, 0, 0, 0, 0); + return info; + } + case ID::R16G16_SINT: + { + static const Format info(ID::R16G16_SINT, + GL_RG16I, + GL_RG16I, + GenerateMip<R16G16S>, + ReadColor<R16G16S, GLint>, + 16, 16, 0, 0, 0, 0); + return info; + } + case ID::R16G16_SNORM: + { + static const Format info(ID::R16G16_SNORM, + GL_RG16_SNORM_EXT, + GL_RG16_SNORM_EXT, + GenerateMip<R16G16S>, + ReadColor<R16G16S, GLfloat>, + 16, 16, 0, 0, 0, 0); + return info; + } + case ID::R16G16_UINT: + { + static const Format info(ID::R16G16_UINT, + GL_RG16UI, + GL_RG16UI, + GenerateMip<R16G16>, + ReadColor<R16G16, GLuint>, + 16, 16, 0, 0, 0, 0); + return info; + } + case ID::R16G16_UNORM: + { + static const Format info(ID::R16G16_UNORM, + GL_RG16_EXT, + GL_RG16_EXT, + GenerateMip<R16G16>, + ReadColor<R16G16, GLfloat>, + 16, 16, 0, 0, 0, 0); + return info; + } + case ID::R16_FLOAT: + { + static const Format info(ID::R16_FLOAT, + GL_R16F, + GL_R16F, + GenerateMip<R16F>, + ReadColor<R16F, GLfloat>, + 16, 0, 0, 0, 0, 0); + return info; + } + case ID::R16_SINT: + { + static const Format info(ID::R16_SINT, + GL_R16I, + GL_R16I, + GenerateMip<R16S>, + ReadColor<R16S, GLint>, + 16, 0, 0, 0, 0, 0); + return info; + } + case ID::R16_SNORM: + { + static const Format info(ID::R16_SNORM, + GL_R16_SNORM_EXT, + GL_R16_SNORM_EXT, + GenerateMip<R16S>, + ReadColor<R16S, GLfloat>, + 16, 0, 0, 0, 0, 0); + return info; + } + case ID::R16_UINT: + { + static const Format info(ID::R16_UINT, + GL_R16UI, + GL_R16UI, + GenerateMip<R16>, + ReadColor<R16, GLuint>, + 16, 0, 0, 0, 0, 0); + return info; + } + case ID::R16_UNORM: + { + static const Format info(ID::R16_UNORM, + GL_R16_EXT, + GL_R16_EXT, + GenerateMip<R16>, + ReadColor<R16, GLfloat>, + 16, 0, 0, 0, 0, 0); + return info; + } + case ID::R32G32B32A32_FLOAT: + { + static const Format info(ID::R32G32B32A32_FLOAT, + GL_RGBA32F, + GL_RGBA32F, + GenerateMip<R32G32B32A32F>, + ReadColor<R32G32B32A32F, GLfloat>, + 32, 32, 32, 32, 0, 0); + return info; + } + case ID::R32G32B32A32_SINT: + { + static const Format info(ID::R32G32B32A32_SINT, + GL_RGBA32I, + GL_RGBA32I, + GenerateMip<R32G32B32A32S>, + ReadColor<R32G32B32A32S, GLint>, + 32, 32, 32, 32, 0, 0); + return info; + } + case ID::R32G32B32A32_UINT: + { + static const Format info(ID::R32G32B32A32_UINT, + GL_RGBA32UI, + GL_RGBA32UI, + GenerateMip<R32G32B32A32>, + ReadColor<R32G32B32A32, GLuint>, + 32, 32, 32, 32, 0, 0); + return info; + } + case ID::R32G32B32_FLOAT: + { + static const Format info(ID::R32G32B32_FLOAT, + GL_RGB32F, + GL_RGB32F, + GenerateMip<R32G32B32F>, + ReadColor<R32G32B32F, GLfloat>, + 32, 32, 32, 0, 0, 0); + return info; + } + case ID::R32G32B32_SINT: + { + static const Format info(ID::R32G32B32_SINT, + GL_RGB32I, + GL_RGB32I, + GenerateMip<R32G32B32S>, + ReadColor<R32G32B32S, GLint>, + 32, 32, 32, 0, 0, 0); + return info; + } + case ID::R32G32B32_UINT: + { + static const Format info(ID::R32G32B32_UINT, + GL_RGB32UI, + GL_RGB32UI, + GenerateMip<R32G32B32>, + ReadColor<R32G32B32, GLuint>, + 32, 32, 32, 0, 0, 0); + return info; + } + case ID::R32G32_FLOAT: + { + static const Format info(ID::R32G32_FLOAT, + GL_RG32F, + GL_RG32F, + GenerateMip<R32G32F>, + ReadColor<R32G32F, GLfloat>, + 32, 32, 0, 0, 0, 0); + return info; + } + case ID::R32G32_SINT: + { + static const Format info(ID::R32G32_SINT, + GL_RG32I, + GL_RG32I, + GenerateMip<R32G32S>, + ReadColor<R32G32S, GLint>, + 32, 32, 0, 0, 0, 0); + return info; + } + case ID::R32G32_UINT: + { + static const Format info(ID::R32G32_UINT, + GL_RG32UI, + GL_RG32UI, + GenerateMip<R32G32>, + ReadColor<R32G32, GLuint>, + 32, 32, 0, 0, 0, 0); + return info; + } + case ID::R32_FLOAT: + { + static const Format info(ID::R32_FLOAT, + GL_R32F, + GL_R32F, + GenerateMip<R32F>, + ReadColor<R32F, GLfloat>, + 32, 0, 0, 0, 0, 0); + return info; + } + case ID::R32_SINT: + { + static const Format info(ID::R32_SINT, + GL_R32I, + GL_R32I, + GenerateMip<R32S>, + ReadColor<R32S, GLint>, + 32, 0, 0, 0, 0, 0); + return info; + } + case ID::R32_UINT: + { + static const Format info(ID::R32_UINT, + GL_R32UI, + GL_R32UI, + GenerateMip<R32>, + ReadColor<R32, GLuint>, + 32, 0, 0, 0, 0, 0); + return info; + } + case ID::R4G4B4A4_UNORM: + { + static const Format info(ID::R4G4B4A4_UNORM, + GL_RGBA4, + GL_RGBA4, + GenerateMip<R4G4B4A4>, + ReadColor<R4G4B4A4, GLfloat>, + 4, 4, 4, 4, 0, 0); + return info; + } + case ID::R5G5B5A1_UNORM: + { + static const Format info(ID::R5G5B5A1_UNORM, + GL_RGB5_A1, + GL_RGB5_A1, + GenerateMip<R5G5B5A1>, + ReadColor<R5G5B5A1, GLfloat>, + 5, 5, 5, 1, 0, 0); + return info; + } + case ID::R5G6B5_UNORM: + { + static const Format info(ID::R5G6B5_UNORM, + GL_RGB565, + GL_RGB565, + GenerateMip<R5G6B5>, + ReadColor<R5G6B5, GLfloat>, + 5, 6, 5, 0, 0, 0); + return info; + } + case ID::R8G8B8A8_SINT: + { + static const Format info(ID::R8G8B8A8_SINT, + GL_RGBA8I, + GL_RGBA8I, + GenerateMip<R8G8B8A8S>, + ReadColor<R8G8B8A8S, GLint>, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::R8G8B8A8_SNORM: + { + static const Format info(ID::R8G8B8A8_SNORM, + GL_RGBA8_SNORM, + GL_RGBA8_SNORM, + GenerateMip<R8G8B8A8S>, + ReadColor<R8G8B8A8S, GLfloat>, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::R8G8B8A8_UINT: + { + static const Format info(ID::R8G8B8A8_UINT, + GL_RGBA8UI, + GL_RGBA8UI, + GenerateMip<R8G8B8A8>, + ReadColor<R8G8B8A8, GLuint>, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::R8G8B8A8_UNORM: + { + static const Format info(ID::R8G8B8A8_UNORM, + GL_RGBA8, + GL_RGBA8, + GenerateMip<R8G8B8A8>, + ReadColor<R8G8B8A8, GLfloat>, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::R8G8B8A8_UNORM_SRGB: + { + static const Format info(ID::R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + GL_SRGB8_ALPHA8, + GenerateMip<R8G8B8A8>, + ReadColor<R8G8B8A8, GLfloat>, + 8, 8, 8, 8, 0, 0); + return info; + } + case ID::R8G8B8_SINT: + { + static const Format info(ID::R8G8B8_SINT, + GL_RGB8I, + GL_RGB8I, + GenerateMip<R8G8B8S>, + ReadColor<R8G8B8S, GLint>, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::R8G8B8_SNORM: + { + static const Format info(ID::R8G8B8_SNORM, + GL_RGB8_SNORM, + GL_RGB8_SNORM, + GenerateMip<R8G8B8S>, + ReadColor<R8G8B8S, GLfloat>, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::R8G8B8_UINT: + { + static const Format info(ID::R8G8B8_UINT, + GL_RGB8UI, + GL_RGB8UI, + GenerateMip<R8G8B8>, + ReadColor<R8G8B8, GLuint>, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::R8G8B8_UNORM: + { + static const Format info(ID::R8G8B8_UNORM, + GL_RGB8, + GL_RGB8, + GenerateMip<R8G8B8>, + ReadColor<R8G8B8, GLfloat>, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::R8G8B8_UNORM_SRGB: + { + static const Format info(ID::R8G8B8_UNORM_SRGB, + GL_SRGB8, + GL_SRGB8, + GenerateMip<R8G8B8>, + ReadColor<R8G8B8, GLfloat>, + 8, 8, 8, 0, 0, 0); + return info; + } + case ID::R8G8_SINT: + { + static const Format info(ID::R8G8_SINT, + GL_RG8I, + GL_RG8I, + GenerateMip<R8G8S>, + ReadColor<R8G8S, GLint>, + 8, 8, 0, 0, 0, 0); + return info; + } + case ID::R8G8_SNORM: + { + static const Format info(ID::R8G8_SNORM, + GL_RG8_SNORM, + GL_RG8_SNORM, + GenerateMip<R8G8S>, + ReadColor<R8G8S, GLfloat>, + 8, 8, 0, 0, 0, 0); + return info; + } + case ID::R8G8_UINT: + { + static const Format info(ID::R8G8_UINT, + GL_RG8UI, + GL_RG8UI, + GenerateMip<R8G8>, + ReadColor<R8G8, GLuint>, + 8, 8, 0, 0, 0, 0); + return info; + } + case ID::R8G8_UNORM: + { + static const Format info(ID::R8G8_UNORM, + GL_RG8, + GL_RG8, + GenerateMip<R8G8>, + ReadColor<R8G8, GLfloat>, + 8, 8, 0, 0, 0, 0); + return info; + } + case ID::R8_SINT: + { + static const Format info(ID::R8_SINT, + GL_R8I, + GL_R8I, + GenerateMip<R8S>, + ReadColor<R8S, GLint>, + 8, 0, 0, 0, 0, 0); + return info; + } + case ID::R8_SNORM: + { + static const Format info(ID::R8_SNORM, + GL_R8_SNORM, + GL_R8_SNORM, + GenerateMip<R8S>, + ReadColor<R8S, GLfloat>, + 8, 0, 0, 0, 0, 0); + return info; + } + case ID::R8_UINT: + { + static const Format info(ID::R8_UINT, + GL_R8UI, + GL_R8UI, + GenerateMip<R8>, + ReadColor<R8, GLuint>, + 8, 0, 0, 0, 0, 0); + return info; + } + case ID::R8_UNORM: + { + static const Format info(ID::R8_UNORM, + GL_R8, + GL_R8, + GenerateMip<R8>, + ReadColor<R8, GLfloat>, + 8, 0, 0, 0, 0, 0); + return info; + } + case ID::R9G9B9E5_SHAREDEXP: + { + static const Format info(ID::R9G9B9E5_SHAREDEXP, + GL_RGB9_E5, + GL_RGB9_E5, + GenerateMip<R9G9B9E5>, + ReadColor<R9G9B9E5, GLfloat>, + 9, 9, 9, 0, 0, 0); + return info; + } + case ID::S8_UINT: + { + static const Format info(ID::S8_UINT, + GL_STENCIL_INDEX8, + GL_STENCIL_INDEX8, + nullptr, + nullptr, + 0, 0, 0, 0, 0, 8); + return info; + } + + default: + UNREACHABLE(); + break; + } + // clang-format on + + static const Format noneInfo(ID::NONE, GL_NONE, GL_NONE, nullptr, nullptr, 0, 0, 0, 0, 0, 0); + return noneInfo; +} + +} // namespace angle diff --git a/chromium/third_party/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h index a5aa65e55fa..5139ee5fd71 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h @@ -23,7 +23,11 @@ class FramebufferAttachmentObjectImpl : angle::NonCopyable virtual ~FramebufferAttachmentObjectImpl() {} virtual gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, - FramebufferAttachmentRenderTarget **rtOut) = 0; + FramebufferAttachmentRenderTarget **rtOut) + { + UNIMPLEMENTED(); + return gl::Error(GL_OUT_OF_MEMORY, "getAttachmentRenderTarget not supported."); + } }; } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/GLImplFactory.h b/chromium/third_party/angle/src/libANGLE/renderer/GLImplFactory.h index 5043a78c013..09f14d72717 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/GLImplFactory.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/GLImplFactory.h @@ -16,6 +16,7 @@ #include "libANGLE/Framebuffer.h" #include "libANGLE/Program.h" #include "libANGLE/Shader.h" +#include "libANGLE/TransformFeedback.h" #include "libANGLE/VertexArray.h" namespace gl @@ -73,7 +74,8 @@ class GLImplFactory : angle::NonCopyable virtual FenceSyncImpl *createFenceSync() = 0; // Transform Feedback creation - virtual TransformFeedbackImpl *createTransformFeedback() = 0; + virtual TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) = 0; // Sampler object creation virtual SamplerImpl *createSampler() = 0; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl.h index 12c4a3ca8c0..45ff0a05a17 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl.h @@ -79,6 +79,12 @@ class ProgramImpl : angle::NonCopyable // Returns false for inactive members. virtual bool getUniformBlockMemberInfo(const std::string &memberUniformName, sh::BlockMemberInfo *memberInfoOut) const = 0; + // CHROMIUM_path_rendering + // Set parameters to control fragment shader input variable interpolation + virtual void setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) = 0; protected: const gl::ProgramState &mState; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl_mock.h b/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl_mock.h index 94fc7ab0d8d..1bc20bbef6a 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl_mock.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/ProgramImpl_mock.h @@ -56,6 +56,8 @@ class MockProgramImpl : public rx::ProgramImpl MOCK_METHOD2(setUniformBlockBinding, void(GLuint, GLuint)); MOCK_CONST_METHOD2(getUniformBlockSize, bool(const std::string &, size_t *)); MOCK_CONST_METHOD2(getUniformBlockMemberInfo, bool(const std::string &, sh::BlockMemberInfo *)); + MOCK_METHOD4(setPathFragmentInputGen, + void(const std::string &, GLenum, GLint, const GLfloat *)); MOCK_METHOD0(destroy, void()); }; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/ShaderImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/ShaderImpl.h index 2ade19a06b1..77f6e9b2242 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/ShaderImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/ShaderImpl.h @@ -22,8 +22,8 @@ class ShaderImpl : angle::NonCopyable virtual ~ShaderImpl() { } // Returns additional ShCompile options. - virtual int prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string *sourcePath) = 0; + virtual ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) = 0; // Returns success for compiling on the driver. Returns success. virtual bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) = 0; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.cpp b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.cpp new file mode 100644 index 00000000000..465d4e3e745 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.cpp @@ -0,0 +1,43 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureImpl.cpp: Defines the abstract rx::TextureImpl classes. + +#include "libANGLE/renderer/TextureImpl.h" + +namespace rx +{ + +TextureImpl::TextureImpl(const gl::TextureState &state) : mState(state) +{ +} + +TextureImpl::~TextureImpl() +{ +} + +gl::Error TextureImpl::copyTexture(GLenum internalFormat, + GLenum type, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION, "CHROMIUM_copy_texture exposed but not implemented."); +} + +gl::Error TextureImpl::copySubTexture(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return gl::Error(GL_INVALID_OPERATION, "CHROMIUM_copy_texture exposed but not implemented."); +} +} diff --git a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h index 597742cca82..45c230729e3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl.h @@ -41,8 +41,8 @@ namespace rx class TextureImpl : public FramebufferAttachmentObjectImpl { public: - TextureImpl(const gl::TextureState &state) : mState(state) {} - virtual ~TextureImpl() {} + TextureImpl(const gl::TextureState &state); + virtual ~TextureImpl(); virtual gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0; @@ -59,6 +59,19 @@ class TextureImpl : public FramebufferAttachmentObjectImpl virtual gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) = 0; + virtual gl::Error copyTexture(GLenum internalFormat, + GLenum type, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); + virtual gl::Error copySubTexture(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); + virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0; virtual gl::Error setEGLImageTarget(GLenum target, egl::Image *image) = 0; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h index 3c69f4a6e9f..8b8f397ac7c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/TextureImpl_mock.h @@ -27,6 +27,14 @@ class MockTextureImpl : public TextureImpl MOCK_METHOD7(setCompressedSubImage, gl::Error(GLenum, size_t, const gl::Box &, GLenum, const gl::PixelUnpackState &, size_t, const uint8_t *)); MOCK_METHOD5(copyImage, gl::Error(GLenum, size_t, const gl::Rectangle &, GLenum, const gl::Framebuffer *)); MOCK_METHOD5(copySubImage, gl::Error(GLenum, size_t, const gl::Offset &, const gl::Rectangle &, const gl::Framebuffer *)); + MOCK_METHOD6(copyTexture, gl::Error(GLenum, GLenum, bool, bool, bool, const gl::Texture *)); + MOCK_METHOD6(copySubTexture, + gl::Error(const gl::Offset &, + const gl::Rectangle &, + bool, + bool, + bool, + const gl::Texture *)); MOCK_METHOD4(setStorage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &)); MOCK_METHOD3(setImageExternal, gl::Error(GLenum, egl::Stream *, const egl::Stream::GLTextureDescription &)); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl.h b/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl.h index 5df7cad87ba..71e6374e74a 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl.h @@ -18,6 +18,7 @@ namespace rx class TransformFeedbackImpl : angle::NonCopyable { public: + TransformFeedbackImpl(const gl::TransformFeedbackState &state) : mState(state) {} virtual ~TransformFeedbackImpl() { } virtual void begin(GLenum primitiveMode) = 0; @@ -27,6 +28,9 @@ class TransformFeedbackImpl : angle::NonCopyable virtual void bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) = 0; virtual void bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding) = 0; + + protected: + const gl::TransformFeedbackState &mState; }; } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h b/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h index c7d2fc620d4..18832acc7c3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h @@ -19,6 +19,10 @@ namespace rx class MockTransformFeedbackImpl : public TransformFeedbackImpl { public: + MockTransformFeedbackImpl(const gl::TransformFeedbackState &state) + : TransformFeedbackImpl(state) + { + } ~MockTransformFeedbackImpl() { destructor(); } MOCK_METHOD1(begin, void(GLenum primitiveMode)); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/angle_format.py b/chromium/third_party/angle/src/libANGLE/renderer/angle_format.py new file mode 100644 index 00000000000..e46bc7dba99 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/angle_format.py @@ -0,0 +1,45 @@ +#!/usr/bin/python +# Copyright 2016 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# angle_format.py: +# Utils for ANGLE formats. + +import json +import os + +def reject_duplicate_keys(pairs): + found_keys = {} + for key, value in pairs: + if key in found_keys: + raise ValueError("duplicate key: %r" % (key,)) + else: + found_keys[key] = value + return found_keys + +def load_json(path): + with open(path) as map_file: + file_data = map_file.read() + map_file.close() + return json.loads(file_data, object_pairs_hook=reject_duplicate_keys) + +def load_forward_table(path): + pairs = load_json(path) + reject_duplicate_keys(pairs) + return { gl: angle for gl, angle in pairs } + +def load_inverse_table(path): + pairs = load_json(path) + reject_duplicate_keys(pairs) + return { angle: gl for gl, angle in pairs } + +def load_with_override(override_path): + map_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'angle_format_map.json') + results = load_forward_table(map_path) + overrides = load_json(override_path) + + for k, v in overrides.iteritems(): + results[k] = v + + return results diff --git a/chromium/third_party/angle/src/libANGLE/renderer/angle_format_data.json b/chromium/third_party/angle/src/libANGLE/renderer/angle_format_data.json new file mode 100644 index 00000000000..b243520d299 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/angle_format_data.json @@ -0,0 +1,21 @@ +{ + "B5G6R5_UNORM": { + "fboImplementationInternalFormat": "GL_RGB565" + }, + "B5G5R5A1_UNORM": { + "fboImplementationInternalFormat": "GL_RGB5_A1", + "channelStruct": "A1R5G5B5" + }, + "B8G8R8X8_UNORM": { + "glInternalFormat": "GL_BGRA8_EXT", + "channelStruct": "B8G8R8X8" + }, + "R9G9B9E5_SHAREDEXP": { + "componentType": "float", + "channelStruct": "R9G9B9E5" + }, + "B4G4R4A4_UNORM": { + "fboImplementationInternalFormat": "GL_RGBA4", + "channelStruct": "A4R4G4B4" + } +} diff --git a/chromium/third_party/angle/src/libANGLE/renderer/angle_format_map.json b/chromium/third_party/angle/src/libANGLE/renderer/angle_format_map.json new file mode 100644 index 00000000000..064c400ace3 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/angle_format_map.json @@ -0,0 +1,127 @@ +[ + [ "GL_ALPHA16F_EXT", "A16_FLOAT" ], + [ "GL_ALPHA32F_EXT", "A32_FLOAT" ], + [ "GL_ALPHA8_EXT", "A8_UNORM" ], + [ "GL_BGR565_ANGLEX", "B5G6R5_UNORM" ], + [ "GL_BGR5_A1_ANGLEX", "B5G5R5A1_UNORM" ], + [ "GL_BGRA4_ANGLEX", "B4G4R4A4_UNORM" ], + [ "GL_BGRA8_EXT", "B8G8R8A8_UNORM" ], + [ "GL_BGRX8_ANGLEX", "B8G8R8X8_UNORM" ], + [ "GL_COMPRESSED_R11_EAC", "EAC_R11_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RG11_EAC", "EAC_R11G11_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGB8_ETC2", "ETC2_R8G8B8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", "ETC2_R8G8B8A1_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA8_ETC2_EAC", "ETC2_R8G8B8A8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT", "BC1_RGBA_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE", "BC2_RGBA_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE", "BC3_RGBA_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_4x4_KHR", "ASTC_4x4_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_5x4_KHR", "ASTC_5x4_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_5x5_KHR", "ASTC_5x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_6x5_KHR", "ASTC_6x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_6x6_KHR", "ASTC_6x6_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_8x5_KHR", "ASTC_8x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_8x6_KHR", "ASTC_8x6_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_8x8_KHR", "ASTC_8x8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x5_KHR", "ASTC_10x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x6_KHR", "ASTC_10x6_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x8_KHR", "ASTC_10x8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x10_KHR", "ASTC_10x10_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_12x10_KHR", "ASTC_12x10_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_12x12_KHR", "ASTC_12x12_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGB_S3TC_DXT1_EXT", "BC1_RGB_UNORM_BLOCK" ], + [ "GL_COMPRESSED_SIGNED_R11_EAC", "EAC_R11_SNORM_BLOCK" ], + [ "GL_COMPRESSED_SIGNED_RG11_EAC", "EAC_R11G11_SNORM_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR", "ASTC_4x4_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR", "ASTC_5x4_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR", "ASTC_5x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR", "ASTC_6x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR", "ASTC_6x6_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR", "ASTC_8x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR", "ASTC_8x6_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR", "ASTC_8x8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR", "ASTC_10x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR", "ASTC_10x6_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR", "ASTC_10x8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR", "ASTC_10x10_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR", "ASTC_12x10_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR", "ASTC_12x12_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", "ETC2_R8G8B8A8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ETC2", "ETC2_R8G8B8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2", "ETC2_R8G8B8A1_SRGB_BLOCK" ], + [ "GL_DEPTH24_STENCIL8", "D24_UNORM_S8_UINT" ], + [ "GL_DEPTH32F_STENCIL8", "D32_FLOAT_S8X24_UINT" ], + [ "GL_DEPTH_COMPONENT16", "D16_UNORM" ], + [ "GL_DEPTH_COMPONENT24", "D24_UNORM" ], + [ "GL_DEPTH_COMPONENT32F", "D32_FLOAT" ], + [ "GL_DEPTH_COMPONENT32_OES", "D32_UNORM" ], + [ "GL_ETC1_RGB8_OES", "NONE" ], + [ "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE", "NONE" ], + [ "GL_LUMINANCE16F_EXT", "L16_FLOAT" ], + [ "GL_LUMINANCE32F_EXT", "L32_FLOAT" ], + [ "GL_LUMINANCE8_ALPHA8_EXT", "L8A8_UNORM" ], + [ "GL_LUMINANCE8_EXT", "L8_UNORM" ], + [ "GL_LUMINANCE_ALPHA16F_EXT", "L16A16_FLOAT" ], + [ "GL_LUMINANCE_ALPHA32F_EXT", "L32A32_FLOAT" ], + [ "GL_NONE", "NONE" ], + [ "GL_R11F_G11F_B10F", "R11G11B10_FLOAT" ], + [ "GL_R16F", "R16_FLOAT" ], + [ "GL_R16I", "R16_SINT" ], + [ "GL_R16UI", "R16_UINT" ], + [ "GL_R32F", "R32_FLOAT" ], + [ "GL_R32I", "R32_SINT" ], + [ "GL_R32UI", "R32_UINT" ], + [ "GL_R8", "R8_UNORM" ], + [ "GL_R8I", "R8_SINT" ], + [ "GL_R8UI", "R8_UINT" ], + [ "GL_R8_SNORM", "R8_SNORM" ], + [ "GL_RG16F", "R16G16_FLOAT" ], + [ "GL_RG16I", "R16G16_SINT" ], + [ "GL_RG16UI", "R16G16_UINT" ], + [ "GL_RG32F", "R32G32_FLOAT" ], + [ "GL_RG32I", "R32G32_SINT" ], + [ "GL_RG32UI", "R32G32_UINT" ], + [ "GL_RG8", "R8G8_UNORM" ], + [ "GL_RG8I", "R8G8_SINT" ], + [ "GL_RG8UI", "R8G8_UINT" ], + [ "GL_RG8_SNORM", "R8G8_SNORM" ], + [ "GL_RGB", "R8G8B8_UNORM" ], + [ "GL_RGB10_A2", "R10G10B10A2_UNORM" ], + [ "GL_RGB10_A2UI", "R10G10B10A2_UINT" ], + [ "GL_RGB16F", "R16G16B16_FLOAT" ], + [ "GL_RGB16I", "R16G16B16_SINT" ], + [ "GL_RGB16UI", "R16G16B16_UINT" ], + [ "GL_RGB32F", "R32G32B32_FLOAT" ], + [ "GL_RGB32I", "R32G32B32_SINT" ], + [ "GL_RGB32UI", "R32G32B32_UINT" ], + [ "GL_RGB565", "R5G6B5_UNORM" ], + [ "GL_RGB5_A1", "R5G5B5A1_UNORM" ], + [ "GL_RGB8", "R8G8B8_UNORM" ], + [ "GL_RGB8I", "R8G8B8_SINT" ], + [ "GL_RGB8UI", "R8G8B8_UINT" ], + [ "GL_RGB8_SNORM", "R8G8B8_SNORM" ], + [ "GL_RGB9_E5", "R9G9B9E5_SHAREDEXP" ], + [ "GL_RGBA", "R8G8B8A8_UNORM" ], + [ "GL_RGBA16F", "R16G16B16A16_FLOAT" ], + [ "GL_RGBA16I", "R16G16B16A16_SINT" ], + [ "GL_RGBA16UI", "R16G16B16A16_UINT" ], + [ "GL_RGBA32F", "R32G32B32A32_FLOAT" ], + [ "GL_RGBA32I", "R32G32B32A32_SINT" ], + [ "GL_RGBA32UI", "R32G32B32A32_UINT" ], + [ "GL_RGBA4", "R4G4B4A4_UNORM" ], + [ "GL_RGBA8", "R8G8B8A8_UNORM" ], + [ "GL_RGBA8I", "R8G8B8A8_SINT" ], + [ "GL_RGBA8UI", "R8G8B8A8_UINT" ], + [ "GL_RGBA8_SNORM", "R8G8B8A8_SNORM" ], + [ "GL_SRGB8", "R8G8B8_UNORM_SRGB" ], + [ "GL_SRGB8_ALPHA8", "R8G8B8A8_UNORM_SRGB" ], + [ "GL_STENCIL_INDEX8", "S8_UINT" ], + [ "GL_R16_EXT", "R16_UNORM" ], + [ "GL_RG16_EXT", "R16G16_UNORM" ], + [ "GL_RGB16_EXT", "R16G16B16_UNORM" ], + [ "GL_RGBA16_EXT", "R16G16B16A16_UNORM" ], + [ "GL_R16_SNORM_EXT", "R16_SNORM" ], + [ "GL_RG16_SNORM_EXT", "R16G16_SNORM" ], + [ "GL_RGB16_SNORM_EXT", "R16G16B16_SNORM" ], + [ "GL_RGBA16_SNORM_EXT", "R16G16B16A16_SNORM" ] +] diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp index abd5e6f7c4e..f5cc97e9514 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp @@ -8,6 +8,8 @@ #include "libANGLE/renderer/d3d/DisplayD3D.h" +#include <EGL/eglext.h> + #include "libANGLE/Context.h" #include "libANGLE/Config.h" #include "libANGLE/Display.h" @@ -19,8 +21,6 @@ #include "libANGLE/renderer/d3d/SwapChainD3D.h" #include "libANGLE/renderer/d3d/DeviceD3D.h" -#include <EGL/eglext.h> - #if defined (ANGLE_ENABLE_D3D9) # include "libANGLE/renderer/d3d/d3d9/Renderer9.h" #endif // ANGLE_ENABLE_D3D9 @@ -247,12 +247,6 @@ egl::ConfigSet DisplayD3D::generateConfigs() return mRenderer->generateConfigs(); } -bool DisplayD3D::isDeviceLost() const -{ - ASSERT(mRenderer != nullptr); - return mRenderer->isDeviceLost(); -} - bool DisplayD3D::testDeviceLost() { ASSERT(mRenderer != nullptr); @@ -323,7 +317,12 @@ void DisplayD3D::generateCaps(egl::Caps *outCaps) const egl::Error DisplayD3D::waitClient() const { - // Unimplemented as it is a noop on D3D + for (auto &surface : getSurfaceSet()) + { + SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface); + surfaceD3D->checkForOutOfDateSwapChain(); + } + return egl::Error(EGL_SUCCESS); } @@ -331,7 +330,24 @@ egl::Error DisplayD3D::waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const { - // Unimplemented as it is a noop on D3D + if (drawSurface != nullptr) + { + SurfaceD3D *drawSurfaceD3D = GetImplAs<SurfaceD3D>(drawSurface); + drawSurfaceD3D->checkForOutOfDateSwapChain(); + } + + if (readSurface != nullptr) + { + SurfaceD3D *readurfaceD3D = GetImplAs<SurfaceD3D>(readSurface); + readurfaceD3D->checkForOutOfDateSwapChain(); + } + return egl::Error(EGL_SUCCESS); } + +gl::Version DisplayD3D::getMaxSupportedESVersion() const +{ + return mRenderer->getMaxSupportedESVersion(); +} + } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.h index 2b55b9cb86b..1bd6f1160e6 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/DisplayD3D.h @@ -55,7 +55,6 @@ class DisplayD3D : public DisplayImpl egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; egl::Error restoreLostDevice() override; @@ -69,6 +68,7 @@ class DisplayD3D : public DisplayImpl egl::Error waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const override; + gl::Version getMaxSupportedESVersion() const override; private: void generateExtensions(egl::DisplayExtensions *outExtensions) const override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp index 2bf3b892726..f6eef6f4cd4 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp @@ -207,7 +207,7 @@ GLenum FramebufferD3D::getImplementationColorReadFormat() const GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget); const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat); - return implementationFormatInfo.format; + return implementationFormatInfo.getReadPixelsFormat(); } GLenum FramebufferD3D::getImplementationColorReadType() const @@ -229,7 +229,7 @@ GLenum FramebufferD3D::getImplementationColorReadType() const GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget); const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat); - return implementationFormatInfo.type; + return implementationFormatInfo.getReadPixelsType(); } gl::Error FramebufferD3D::readPixels(ContextImpl *context, @@ -242,13 +242,13 @@ gl::Error FramebufferD3D::readPixels(ContextImpl *context, GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type); const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); - GLuint outputPitch = 0; + + GLuint outputPitch = 0; ANGLE_TRY_RESULT( sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength), outputPitch); GLuint outputSkipBytes = 0; - ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, 0, packState.skipRows, - packState.skipPixels, false), + ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false), outputSkipBytes); return readPixelsImpl(area, format, type, outputPitch, packState, @@ -309,33 +309,10 @@ bool FramebufferD3D::checkStatus() const return false; } - // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness by checking the - // enabled draw buffers - for (size_t firstDrawBufferIdx = 0; firstDrawBufferIdx < mState.getDrawBufferCount(); - firstDrawBufferIdx++) + // D3D11 does not allow for overlapping RenderTargetViews + if (!mState.colorAttachmentsAreUniqueImages()) { - const gl::FramebufferAttachment *firstAttachment = mState.getDrawBuffer(firstDrawBufferIdx); - if (firstAttachment == nullptr) - { - continue; - } - - for (size_t secondDrawBufferIdx = firstDrawBufferIdx + 1; - secondDrawBufferIdx < mState.getDrawBufferCount(); secondDrawBufferIdx++) - { - const gl::FramebufferAttachment *secondAttachment = - mState.getDrawBuffer(secondDrawBufferIdx); - if (secondAttachment == nullptr) - { - continue; - } - - if (firstAttachment->id() == secondAttachment->id() && - firstAttachment->type() == secondAttachment->type()) - { - return false; - } - } + return false; } // D3D requires all render targets to have the same dimensions. diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h index b2524d537b2..e56ee7c0b01 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h @@ -12,6 +12,7 @@ #include <vector> #include <cstdint> +#include "common/Color.h" #include "common/Optional.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/FramebufferImpl.h" diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp index e8b1af31291..305b6c4e4ac 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp @@ -136,7 +136,8 @@ gl::Error HLSLCompiler::initialize() if (!mD3DCompilerModule) { - return gl::Error(GL_INVALID_OPERATION, "No D3D compiler module found - aborting!\n"); + ERR("D3D compiler module not found."); + return gl::Error(GL_OUT_OF_MEMORY, "D3D compiler module not found."); } mD3DCompileFunc = reinterpret_cast<pD3DCompile>(GetProcAddress(mD3DCompilerModule, "D3DCompile")); @@ -155,7 +156,7 @@ gl::Error HLSLCompiler::initialize() if (mD3DCompileFunc == nullptr) { - return gl::Error(GL_INVALID_OPERATION, "Error finding D3DCompile entry point"); + return gl::Error(GL_OUT_OF_MEMORY, "Error finding D3DCompile entry point."); } mInitialized = true; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp index d62bb7244a1..5c949945bc1 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp @@ -377,16 +377,14 @@ D3DVarying::D3DVarying(const std::string &semanticNameIn, // ProgramD3DMetadata Implementation -ProgramD3DMetadata::ProgramD3DMetadata(int rendererMajorShaderModel, - const std::string &shaderModelSuffix, - bool usesInstancedPointSpriteEmulation, - bool usesViewScale, +ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer, const ShaderD3D *vertexShader, const ShaderD3D *fragmentShader) - : mRendererMajorShaderModel(rendererMajorShaderModel), - mShaderModelSuffix(shaderModelSuffix), - mUsesInstancedPointSpriteEmulation(usesInstancedPointSpriteEmulation), - mUsesViewScale(usesViewScale), + : mRendererMajorShaderModel(renderer->getMajorShaderModel()), + mShaderModelSuffix(renderer->getShaderModelSuffix()), + mUsesInstancedPointSpriteEmulation( + renderer->getWorkarounds().useInstancedPointSpriteEmulation), + mUsesViewScale(renderer->presentPathFastEnabled()), mVertexShader(vertexShader), mFragmentShader(fragmentShader) { @@ -399,7 +397,7 @@ int ProgramD3DMetadata::getRendererMajorShaderModel() const bool ProgramD3DMetadata::usesBroadcast(const gl::ContextState &data) const { - return (mFragmentShader->usesFragColor() && data.getClientVersion() < 3); + return (mFragmentShader->usesFragColor() && data.getClientMajorVersion() < 3); } bool ProgramD3DMetadata::usesFragDepth() const @@ -424,7 +422,8 @@ bool ProgramD3DMetadata::usesPointSize() const bool ProgramD3DMetadata::usesInsertedPointCoordValue() const { - return !usesPointSize() && usesPointCoord() && mRendererMajorShaderModel >= 4; + return (!usesPointSize() || !mUsesInstancedPointSpriteEmulation) && usesPointCoord() && + mRendererMajorShaderModel >= 4; } bool ProgramD3DMetadata::usesViewScale() const @@ -434,13 +433,12 @@ bool ProgramD3DMetadata::usesViewScale() const bool ProgramD3DMetadata::addsPointCoordToVertexShader() const { - // Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader + // PointSprite emulation requiress that gl_PointCoord is present in the vertex shader // VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader. - // GeometryShader PointSprite emulation does not require this additional entry because the - // GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the - // PS_INPUT of the generated pixel shader. The Geometry Shader point sprite implementation needs - // gl_PointSize to be in VS_OUTPUT and GS_INPUT. Instanced point sprites doesn't need - // gl_PointSize in VS_OUTPUT. + // Even with a geometry shader, the app can render triangles or lines and reference + // gl_PointCoord in the fragment shader, requiring us to provide a dummy value. For + // simplicity, we always add this to the vertex shader when the fragment shader + // references gl_PointCoord, even if we could skip it in the geometry shader. return (mUsesInstancedPointSpriteEmulation && usesPointCoord()) || usesInsertedPointCoordValue(); } @@ -1380,10 +1378,7 @@ LinkResult ProgramD3D::link(const gl::ContextState &data, gl::InfoLog &infoLog) return LinkResult(false, gl::Error(GL_NO_ERROR)); } - ProgramD3DMetadata metadata(mRenderer->getMajorShaderModel(), mRenderer->getShaderModelSuffix(), - usesInstancedPointSpriteEmulation(), - mRenderer->presentPathFastEnabled(), vertexShaderD3D, - fragmentShaderD3D); + ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D); varyingPacking.enableBuiltins(SHADER_VERTEX, metadata); varyingPacking.enableBuiltins(SHADER_PIXEL, metadata); @@ -1438,7 +1433,12 @@ LinkResult ProgramD3D::link(const gl::ContextState &data, gl::InfoLog &infoLog) gatherTransformFeedbackVaryings(varyingPacking); LinkResult result = compileProgramExecutables(data, infoLog); - if (result.error.isError() || !result.linkSuccess) + if (result.error.isError()) + { + infoLog << result.error.getMessage(); + return result; + } + else if (!result.linkSuccess) { infoLog << "Failed to create D3D shaders."; return result; @@ -2309,4 +2309,13 @@ bool ProgramD3D::getUniformBlockMemberInfo(const std::string &memberUniformName, *memberInfoOut = infoIter->second; return true; } + +void ProgramD3D::setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + UNREACHABLE(); +} + } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.h index 18bc1eb2502..88fe4020db3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ProgramD3D.h @@ -97,13 +97,10 @@ struct D3DVarying final unsigned int outputSlot; }; -class ProgramD3DMetadata : angle::NonCopyable +class ProgramD3DMetadata final : angle::NonCopyable { public: - ProgramD3DMetadata(int rendererMajorShaderModel, - const std::string &shaderModelSuffix, - bool usesInstancedPointSpriteEmulation, - bool usesViewScale, + ProgramD3DMetadata(RendererD3D *renderer, const ShaderD3D *vertexShader, const ShaderD3D *fragmentShader); @@ -174,6 +171,10 @@ class ProgramD3D : public ProgramImpl bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override; bool getUniformBlockMemberInfo(const std::string &memberUniformName, sh::BlockMemberInfo *memberInfoOut) const override; + void setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) override; void initializeUniformStorage(); gl::Error applyUniforms(GLenum drawMode); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp index 1be680f713c..e7e22efc515 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp @@ -31,11 +31,11 @@ namespace rx RendererD3D::RendererD3D(egl::Display *display) : mDisplay(display), - mDeviceLost(false), mPresentPathFastEnabled(false), mCapsInitialized(false), mWorkaroundsInitialized(false), - mDisjoint(false) + mDisjoint(false), + mDeviceLost(false) { } @@ -275,14 +275,29 @@ gl::Texture *RendererD3D::getIncompleteTexture(GLImplFactory *implFactory, GLenu return mIncompleteTextures[type].get(); } -bool RendererD3D::isDeviceLost() const +GLenum RendererD3D::getResetStatus() { - return mDeviceLost; + if (!mDeviceLost) + { + if (testDeviceLost()) + { + mDeviceLost = true; + notifyDeviceLost(); + return GL_UNKNOWN_CONTEXT_RESET_EXT; + } + return GL_NO_ERROR; + } + + if (testDeviceResettable()) + { + return GL_NO_ERROR; + } + + return GL_UNKNOWN_CONTEXT_RESET_EXT; } void RendererD3D::notifyDeviceLost() { - mDeviceLost = true; mDisplay->notifyDeviceLost(); } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.h index 440e1c879ba..9378b68b35e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/RendererD3D.h @@ -17,6 +17,7 @@ #include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" #include "libANGLE/renderer/d3d/WorkaroundsD3D.h" +#include "libANGLE/Version.h" //FIXME(jmadill): std::array is currently prohibited by Chromium style guide #include <array> @@ -111,8 +112,6 @@ class RendererD3D : public BufferFactoryD3D virtual ContextImpl *createContext(const gl::ContextState &state) = 0; - bool isDeviceLost() const; - virtual bool testDeviceLost() = 0; std::string getVendorString() const; virtual int getMinorShaderModel() const = 0; @@ -160,6 +159,17 @@ class RendererD3D : public BufferFactoryD3D virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0; + virtual gl::Error copyTexture(const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) = 0; + // RenderTarget creation virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) = 0; virtual gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) = 0; @@ -186,7 +196,8 @@ class RendererD3D : public BufferFactoryD3D virtual gl::Error generateMipmapUsingD3D(TextureStorage *storage, const gl::TextureState &textureState) = 0; virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) = 0; - virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) = 0; + virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) = 0; virtual TextureStorage *createTextureStorageExternal( egl::Stream *stream, const egl::Stream::GLTextureDescription &desc) = 0; @@ -201,8 +212,12 @@ class RendererD3D : public BufferFactoryD3D GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0; // Device lost + GLenum getResetStatus(); void notifyDeviceLost(); virtual bool resetDevice() = 0; + virtual bool testDeviceLost() = 0; + virtual bool testDeviceResettable() = 0; + virtual RendererClass getRendererClass() const = 0; virtual void *getD3DDevice() = 0; @@ -231,6 +246,8 @@ class RendererD3D : public BufferFactoryD3D // Necessary hack for default framebuffers in D3D. virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0; + virtual gl::Version getMaxSupportedESVersion() const = 0; + protected: virtual bool getLUID(LUID *adapterLuid) const = 0; virtual void generateCaps(gl::Caps *outCaps, @@ -248,7 +265,6 @@ class RendererD3D : public BufferFactoryD3D gl::Error markTransformFeedbackUsage(const gl::ContextState &data); egl::Display *mDisplay; - bool mDeviceLost; bool mPresentPathFastEnabled; @@ -281,6 +297,7 @@ class RendererD3D : public BufferFactoryD3D mutable WorkaroundsD3D mWorkarounds; bool mDisjoint; + bool mDeviceLost; }; } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp index 2e0d56ce357..02489312cbe 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp @@ -40,9 +40,33 @@ const char *GetShaderTypeString(GLenum type) namespace rx { -ShaderD3D::ShaderD3D(const gl::ShaderState &data) : ShaderImpl(data) +ShaderD3D::ShaderD3D(const gl::ShaderState &data, const WorkaroundsD3D &workarounds) + : ShaderImpl(data), mAdditionalOptions(0) { uncompile(); + + if (workarounds.expandIntegerPowExpressions) + { + mAdditionalOptions |= SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS; + } + + if (workarounds.getDimensionsIgnoresBaseLevel) + { + mAdditionalOptions |= SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL; + } + + if (workarounds.preAddTexelFetchOffsets) + { + mAdditionalOptions |= SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH; + } + if (workarounds.rewriteUnaryMinusOperator) + { + mAdditionalOptions |= SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR; + } + if (workarounds.emulateIsnanFloat) + { + mAdditionalOptions |= SH_EMULATE_ISNAN_FLOAT_FUNCTION; + } } ShaderD3D::~ShaderD3D() @@ -117,12 +141,12 @@ ShShaderOutput ShaderD3D::getCompilerOutputType() const return mCompilerOutputType; } -int ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStream, - std::string *sourcePath) +ShCompileOptions ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStream, + std::string *sourcePath) { uncompile(); - int additionalOptions = 0; + ShCompileOptions additionalOptions = 0; const std::string &source = mData.getSource(); @@ -135,6 +159,8 @@ int ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStre } #endif + additionalOptions |= mAdditionalOptions; + *shaderSourceStream << source; return additionalOptions; } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.h index 8346d2dc627..587c1217304 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/ShaderD3D.h @@ -19,16 +19,17 @@ class DynamicHLSL; class RendererD3D; struct D3DCompilerWorkarounds; struct D3DUniform; +struct WorkaroundsD3D; class ShaderD3D : public ShaderImpl { public: - ShaderD3D(const gl::ShaderState &data); + ShaderD3D(const gl::ShaderState &data, const WorkaroundsD3D &workarounds); virtual ~ShaderD3D(); // ShaderImpl implementation - int prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string *sourcePath) override; + ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) override; bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override; std::string getDebugInfo() const override; @@ -76,7 +77,8 @@ class ShaderD3D : public ShaderImpl mutable std::string mDebugInfo; std::map<std::string, unsigned int> mUniformRegisterMap; std::map<std::string, unsigned int> mInterfaceBlockRegisterMap; + ShCompileOptions mAdditionalOptions; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_SHADERD3D_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h index 71602b76641..992c68bc527 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h @@ -44,8 +44,8 @@ class SwapChainD3D : angle::NonCopyable virtual RenderTargetD3D *getColorRenderTarget() = 0; virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0; - GLenum GetRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; } - GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; } + GLenum getRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; } + GLenum getDepthBufferInternalFormat() const { return mDepthBufferFormat; } HANDLE getShareHandle() { return mShareHandle; } virtual void *getKeyedMutex() = 0; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp index bf637c92c05..96e8e20ff03 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp @@ -410,6 +410,7 @@ gl::Error TextureD3D::generateMipmap() const GLuint baseLevel = mState.getEffectiveBaseLevel(); const GLuint maxLevel = mState.getMipmapMaxLevel(); ASSERT(maxLevel > baseLevel); // Should be checked before calling this. + UNUSED_ASSERTION_VARIABLE(baseLevel); if (mTexStorage && mRenderer->getWorkarounds().zeroMaxLodWorkaround) { @@ -910,6 +911,63 @@ gl::Error TextureD3D_2D::copySubImage(GLenum target, return gl::Error(GL_NO_ERROR); } +gl::Error TextureD3D_2D::copyTexture(GLenum internalFormat, + GLenum type, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + GLenum sourceTarget = source->getTarget(); + GLint sourceLevel = 0; + + GLint destLevel = 0; + + GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)), + static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1); + redefineImage(destLevel, sizedInternalFormat, size, false); + + ASSERT(canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel))); + + ANGLE_TRY(ensureRenderTarget()); + ASSERT(isValidLevel(destLevel)); + ANGLE_TRY(updateStorageLevel(destLevel)); + + gl::Rectangle sourceRect(0, 0, size.width, size.height); + gl::Offset destOffset(0, 0, 0); + ANGLE_TRY(mRenderer->copyTexture(source, sourceLevel, sourceRect, + gl::GetInternalFormatInfo(sizedInternalFormat).format, + destOffset, mTexStorage, destLevel, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + return gl::NoError(); +} + +gl::Error TextureD3D_2D::copySubTexture(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + GLint sourceLevel = 0; + GLint destLevel = 0; + + ASSERT(canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel))); + + ANGLE_TRY(ensureRenderTarget()); + ASSERT(isValidLevel(destLevel)); + ANGLE_TRY(updateStorageLevel(destLevel)); + + ANGLE_TRY(mRenderer->copyTexture(source, sourceLevel, sourceArea, + gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, + destOffset, mTexStorage, destLevel, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + return gl::NoError(); +} + gl::Error TextureD3D_2D::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) { ASSERT(GL_TEXTURE_2D && size.depth == 1); @@ -990,9 +1048,9 @@ gl::Error TextureD3D_2D::setEGLImageTarget(GLenum target, egl::Image *image) EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image); // Set the properties of the base mip level from the EGL image - GLenum internalformat = image->getInternalFormat(); + const auto &format = image->getFormat(); gl::Extents size(static_cast<int>(image->getWidth()), static_cast<int>(image->getHeight()), 1); - redefineImage(0, internalformat, size, true); + redefineImage(0, format.asSized(), size, true); // Clear all other images. for (size_t level = 1; level < ArraySize(mImageArray); level++) @@ -1003,7 +1061,11 @@ gl::Error TextureD3D_2D::setEGLImageTarget(GLenum target, egl::Image *image) SafeDelete(mTexStorage); mImageArray[0]->markClean(); - mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d); + // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error. + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(eglImaged3d->getRenderTarget(&renderTargetD3D)); + + mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D); mEGLImageTarget = true; return gl::Error(GL_NO_ERROR); @@ -3265,8 +3327,12 @@ gl::Error TextureD3D_External::setEGLImageTarget(GLenum target, egl::Image *imag { EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image); + // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error. + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(eglImaged3d->getRenderTarget(&renderTargetD3D)); + SafeDelete(mTexStorage); - mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d); + mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D); return gl::NoError(); } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h index cac2c693348..7a8cad9801e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TextureD3D.h @@ -158,6 +158,19 @@ class TextureD3D_2D : public TextureD3D gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; + gl::Error copyTexture(GLenum internalFormat, + GLenum type, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + gl::Error copySubTexture(const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override; virtual void bindTexImage(egl::Surface *surface); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp deleted file mode 100644 index 80a4ec3ae1a..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers. - -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" - -namespace rx -{ - -TransformFeedbackD3D::TransformFeedbackD3D() -{ -} - -TransformFeedbackD3D::~TransformFeedbackD3D() -{ -} - -void TransformFeedbackD3D::begin(GLenum primitiveMode) -{ -} - -void TransformFeedbackD3D::end() -{ -} - -void TransformFeedbackD3D::pause() -{ -} - -void TransformFeedbackD3D::resume() -{ -} - -void TransformFeedbackD3D::bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) -{ -} - -void TransformFeedbackD3D::bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding) -{ -} - -} diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h deleted file mode 100644 index 69259661530..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// TransformFeedbackD3D.h: Implements the abstract rx::TransformFeedbackImpl class. - -#ifndef LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ -#define LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ - -#include "libANGLE/renderer/TransformFeedbackImpl.h" -#include "libANGLE/angletypes.h" - -namespace rx -{ - -class TransformFeedbackD3D : public TransformFeedbackImpl -{ - public: - TransformFeedbackD3D(); - virtual ~TransformFeedbackD3D(); - - void begin(GLenum primitiveMode) override; - void end() override; - void pause() override; - void resume() override; - - void bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) override; - void bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding) override; -}; - -} - -#endif // LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp index f2654d34e33..a8fe46ded1f 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp @@ -267,33 +267,37 @@ bool VaryingPacking::packVaryings(gl::InfoLog &infoLog, continue; } + bool found = false; for (const PackedVarying &packedVarying : packedVaryings) { const auto &varying = *packedVarying.varying; // Make sure transform feedback varyings aren't optimized out. - if (uniqueVaryingNames.count(transformFeedbackVaryingName) == 0) + if (uniqueVaryingNames.count(transformFeedbackVaryingName) > 0) { - bool found = false; - if (transformFeedbackVaryingName == varying.name) - { - if (!packVarying(packedVarying)) - { - infoLog << "Could not pack varying " << varying.name; - return false; - } - - found = true; - break; - } - if (!found) + found = true; + break; + } + + if (transformFeedbackVaryingName == varying.name) + { + if (!packVarying(packedVarying)) { - infoLog << "Transform feedback varying " << transformFeedbackVaryingName - << " does not exist in the vertex shader."; + infoLog << "Could not pack varying " << varying.name; return false; } + + found = true; + break; } } + + if (!found) + { + infoLog << "Transform feedback varying " << transformFeedbackVaryingName + << " does not exist in the vertex shader."; + return false; + } } // Sort the packed register list diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h index 58f65f6496b..8dccff3043c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h @@ -17,35 +17,22 @@ namespace rx { struct D3DCompilerWorkarounds { - D3DCompilerWorkarounds() - : skipOptimization(false), useMaxOptimization(false), enableIEEEStrictness(false) - { - } - - bool skipOptimization; - bool useMaxOptimization; + bool skipOptimization = false; + bool useMaxOptimization = false; // IEEE strictness needs to be enabled for NANs to work. - bool enableIEEEStrictness; + bool enableIEEEStrictness = false; }; struct WorkaroundsD3D { - WorkaroundsD3D() - : mrtPerfWorkaround(false), - setDataFasterThanImageUpload(false), - zeroMaxLodWorkaround(false), - useInstancedPointSpriteEmulation(false) - { - } - // On some systems, having extra rendertargets than necessary slows down the shader. // We can fix this by optimizing those out of the shader. At the same time, we can // work around a bug on some nVidia drivers that they ignore "null" render targets // in D3D11, by compacting the active color attachments list to omit null entries. - bool mrtPerfWorkaround; + bool mrtPerfWorkaround = false; - bool setDataFasterThanImageUpload; + bool setDataFasterThanImageUpload = false; // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level // zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to @@ -54,13 +41,61 @@ struct WorkaroundsD3D // application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST // (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the // texture. The textures' level zeros are identical, but only one texture has mips. - bool zeroMaxLodWorkaround; + bool zeroMaxLodWorkaround = false; // Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite // emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite // emulation that is implemented using instanced quads. - bool useInstancedPointSpriteEmulation; + bool useInstancedPointSpriteEmulation = false; + + // A bug fixed in NVIDIA driver version 347.88 < x <= 368.81 triggers a TDR when using + // CopySubresourceRegion from a staging texture to a depth/stencil in D3D11. The workaround + // is to use UpdateSubresource to trigger an extra copy. We disable this workaround on newer + // NVIDIA driver versions because of a second driver bug present with the workaround enabled. + // (See: http://anglebug.com/1452) + bool depthStencilBlitExtraCopy = false; + + // The HLSL optimizer has a bug with optimizing "pow" in certain integer-valued expressions. + // We can work around this by expanding the pow into a series of multiplies if we're running + // under the affected compiler. + bool expandIntegerPowExpressions = false; + + // NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform + // feedback is used to repeatedly write to the same buffer positions. + bool flushAfterEndingTransformFeedback = false; + + // Some drivers (NVIDIA) do not take into account the base level of the texture in the results + // of the HLSL GetDimensions builtin. + bool getDimensionsIgnoresBaseLevel = false; + + // On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location + // is negative, even if the sum of Offset and Location is in range. This may cause errors when + // translating GLSL's function texelFetchOffset into texture.Load, as it is valid for + // texelFetchOffset to use negative texture coordinates as its parameter P when the sum of P + // and Offset is in range. To work around this, we translate texelFetchOffset into texelFetch + // by adding Offset directly to Location before reading the texture. + bool preAddTexelFetchOffsets = false; + + // On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly. + // We can work around this bug by doing an internal blit to a temporary single-channel texture + // before we sample. + bool emulateTinyStencilTextures = false; + + // In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly. + // This workaroud will disable B5G6R5 support when it's Intel driver. By default, it will use + // R8G8B8A8 format. + bool disableB5G6R5Support = false; + + // On some Intel drivers, evaluating unary minus operator on integer may get wrong answer in + // vertex shaders. To work around this bug, we translate -(int) into ~(int)+1. + bool rewriteUnaryMinusOperator = false; + + // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around + // this bug, we use an expression to emulate function isnan(). Tracking bug: + // https://crbug.com/650547 + bool emulateIsnanFloat = false; }; -} + +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp index 62636356e9b..f40a27bbfa7 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp @@ -12,16 +12,29 @@ #include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "third_party/trace_event/trace_event.h" +namespace rx +{ + +namespace +{ + +// Include inline shaders in the anonymous namespace to make sure no symbols are exported #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbapremultiply2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbaunmultiply2d11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbpremultiply2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbunmultiply2d11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h" @@ -50,6 +63,11 @@ #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h" + #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h" @@ -60,12 +78,6 @@ #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h" -namespace rx -{ - -namespace -{ - void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea, const gl::Box &destArea, const gl::Rectangle &clippedDestArea, @@ -179,6 +191,198 @@ void StretchedBlitNearest(const gl::Box &sourceArea, } } +using DepthStencilLoader = void(const float *, uint8_t *); + +void LoadDepth16(const float *source, uint8_t *dest) +{ + uint32_t convertedDepth = gl::floatToNormalized<16, uint32_t>(source[0]); + memcpy(dest, &convertedDepth, 2u); +} + +void LoadDepth24(const float *source, uint8_t *dest) +{ + uint32_t convertedDepth = gl::floatToNormalized<24, uint32_t>(source[0]); + memcpy(dest, &convertedDepth, 3u); +} + +void LoadStencilHelper(const float *source, uint8_t *dest) +{ + uint32_t convertedStencil = gl::getShiftedData<8, 0>(static_cast<uint32_t>(source[1])); + memcpy(dest, &convertedStencil, 1u); +} + +void LoadStencil8(const float *source, uint8_t *dest) +{ + // STENCIL_INDEX8 is implemented with D24S8, with the depth bits unused. Writes zero for safety. + float zero = 0.0f; + LoadDepth24(&zero, &dest[0]); + LoadStencilHelper(source, &dest[3]); +} + +void LoadDepth24Stencil8(const float *source, uint8_t *dest) +{ + LoadDepth24(source, &dest[0]); + LoadStencilHelper(source, &dest[3]); +} + +void LoadDepth32F(const float *source, uint8_t *dest) +{ + memcpy(dest, source, sizeof(float)); +} + +void LoadDepth32FStencil8(const float *source, uint8_t *dest) +{ + LoadDepth32F(source, &dest[0]); + LoadStencilHelper(source, &dest[4]); +} + +template <DepthStencilLoader loader> +void CopyDepthStencil(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const float *sourcePixel = reinterpret_cast<const float *>(sourceData + offset); + + uint8_t *destPixel = destData + row * destRowPitch + column * destPixelStride; + + loader(sourcePixel, destPixel); + } + } +} + +void Depth32FStencil8ToDepth32F(const float *source, float *dest) +{ + *dest = *source; +} + +void Depth24Stencil8ToDepth32F(const uint32_t *source, float *dest) +{ + uint32_t normDepth = source[0] & 0x00FFFFFF; + float floatDepth = gl::normalizedToFloat<24>(normDepth); + *dest = floatDepth; +} + +void BlitD24S8ToD32F(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const uint32_t *sourcePixel = reinterpret_cast<const uint32_t *>(sourceData + offset); + + float *destPixel = + reinterpret_cast<float *>(destData + row * destRowPitch + column * destPixelStride); + + Depth24Stencil8ToDepth32F(sourcePixel, destPixel); + } + } +} + +void BlitD32FS8ToD32F(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const float *sourcePixel = reinterpret_cast<const float *>(sourceData + offset); + float *destPixel = + reinterpret_cast<float *>(destData + row * destRowPitch + column * destPixelStride); + + Depth32FStencil8ToDepth32F(sourcePixel, destPixel); + } + } +} + +Blit11::BlitConvertFunction *GetCopyDepthStencilFunction(GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_DEPTH_COMPONENT16: + return &CopyDepthStencil<LoadDepth16>; + case GL_DEPTH_COMPONENT24: + return &CopyDepthStencil<LoadDepth24>; + case GL_DEPTH_COMPONENT32F: + return &CopyDepthStencil<LoadDepth32F>; + case GL_STENCIL_INDEX8: + return &CopyDepthStencil<LoadStencil8>; + case GL_DEPTH24_STENCIL8: + return &CopyDepthStencil<LoadDepth24Stencil8>; + case GL_DEPTH32F_STENCIL8: + return &CopyDepthStencil<LoadDepth32FStencil8>; + default: + UNREACHABLE(); + return nullptr; + } +} + inline void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &sourceSize, const gl::Box &destArea, @@ -265,7 +469,7 @@ void Write3DVertices(const gl::Box &sourceArea, *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; } -inline unsigned int GetSwizzleIndex(GLenum swizzle) +unsigned int GetSwizzleIndex(GLenum swizzle) { unsigned int colorIndex = 0; @@ -325,6 +529,20 @@ D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = { {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; +DXGI_FORMAT GetStencilSRVFormat(const d3d11::Format &formatSet) +{ + switch (formatSet.texFormat) + { + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + default: + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + } // namespace Blit11::Blit11(Renderer11 *renderer) @@ -353,7 +571,19 @@ Blit11::Blit11(Renderer11 *renderer) mQuad3DVS(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), "Blit11 3D vertex shader"), mQuad3DGS(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), "Blit11 3D geometry shader"), mAlphaMaskBlendState(GetAlphaMaskBlendStateDesc(), "Blit11 Alpha Mask Blend"), - mSwizzleCB(nullptr) + mSwizzleCB(nullptr), + mResolveDepthStencilVS(g_VS_ResolveDepthStencil, + ArraySize(g_VS_ResolveDepthStencil), + "Blit11::mResolveDepthStencilVS"), + mResolveDepthPS(g_PS_ResolveDepth, ArraySize(g_PS_ResolveDepth), "Blit11::mResolveDepthPS"), + mResolveDepthStencilPS(g_PS_ResolveDepthStencil, + ArraySize(g_PS_ResolveDepthStencil), + "Blit11::mResolveDepthStencilPS"), + mResolveStencilPS(g_PS_ResolveStencil, + ArraySize(g_PS_ResolveStencil), + "Blit11::mResolveStencilPS"), + mStencilSRV(nullptr), + mResolvedDepthStencilRTView(nullptr) { } @@ -370,6 +600,7 @@ Blit11::~Blit11() mQuad3DGS.release(); clearShaderMap(); + releaseResolveDepthStencilResources(); } gl::Error Blit11::initResources() @@ -556,10 +787,14 @@ void Blit11::freeResources() // static Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, ShaderDimension dimension) { if (dimension == SHADER_3D) { + ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha); + if (isSigned) { switch (destinationFormat) @@ -613,6 +848,8 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, } else if (isSigned) { + ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha); + switch (destinationFormat) { case GL_RGBA_INTEGER: @@ -630,35 +867,56 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, } else { - switch (destinationFormat) + if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha) { - case GL_RGBA: - return BLITSHADER_2D_RGBAF; - case GL_RGBA_INTEGER: - return BLITSHADER_2D_RGBAUI; - case GL_BGRA_EXT: - return BLITSHADER_2D_BGRAF; - case GL_RGB: - return BLITSHADER_2D_RGBF; - case GL_RGB_INTEGER: - return BLITSHADER_2D_RGBUI; - case GL_RG: - return BLITSHADER_2D_RGF; - case GL_RG_INTEGER: - return BLITSHADER_2D_RGUI; - case GL_RED: - return BLITSHADER_2D_RF; - case GL_RED_INTEGER: - return BLITSHADER_2D_RUI; - case GL_ALPHA: - return BLITSHADER_2D_ALPHA; - case GL_LUMINANCE: - return BLITSHADER_2D_LUMA; - case GL_LUMINANCE_ALPHA: - return BLITSHADER_2D_LUMAALPHA; - default: - UNREACHABLE(); - return BLITSHADER_INVALID; + switch (destinationFormat) + { + case GL_RGBA: + return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBAF_PREMULTIPLY + : BLITSHADER_2D_RGBAF_UNMULTIPLY; + case GL_BGRA_EXT: + return unpackPremultiplyAlpha ? BLITSHADER_2D_BGRAF_PREMULTIPLY + : BLITSHADER_2D_BGRAF_UNMULTIPLY; + case GL_RGB: + return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBF_PREMULTIPLY + : BLITSHADER_2D_RGBF_UNMULTIPLY; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + } + else + { + switch (destinationFormat) + { + case GL_RGBA: + return BLITSHADER_2D_RGBAF; + case GL_RGBA_INTEGER: + return BLITSHADER_2D_RGBAUI; + case GL_BGRA_EXT: + return BLITSHADER_2D_BGRAF; + case GL_RGB: + return BLITSHADER_2D_RGBF; + case GL_RGB_INTEGER: + return BLITSHADER_2D_RGBUI; + case GL_RG: + return BLITSHADER_2D_RGF; + case GL_RG_INTEGER: + return BLITSHADER_2D_RGUI; + case GL_RED: + return BLITSHADER_2D_RF; + case GL_RED_INTEGER: + return BLITSHADER_2D_RUI; + case GL_ALPHA: + return BLITSHADER_2D_ALPHA; + case GL_LUMINANCE: + return BLITSHADER_2D_LUMA; + case GL_LUMINANCE_ALPHA: + return BLITSHADER_2D_LUMAALPHA; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } } } } @@ -911,7 +1169,9 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle *scissor, GLenum destFormat, GLenum filter, - bool maskOffAlpha) + bool maskOffAlpha, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) { ANGLE_TRY(initResources()); @@ -934,7 +1194,9 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D; const Shader *shader = nullptr; - ANGLE_TRY(getBlitShader(destFormat, isSigned, dimension, &shader)); + ANGLE_TRY(getBlitShader(destFormat, isSigned, unpackPremultiplyAlpha, unpackUnmultiplyAlpha, + dimension, &shader)); + const ShaderSupport &support = getShaderSupport(*shader); // Set vertices @@ -1197,22 +1459,26 @@ gl::Error Blit11::copyDepthStencilImpl(const TextureHelper11 &source, const gl::Rectangle *scissor, bool stencilOnly) { - ASSERT(source.getANGLEFormat() == dest.getANGLEFormat()); + auto srcDXGIFormat = source.getFormat(); + const auto &srcSizeInfo = d3d11::GetDXGIFormatSizeInfo(srcDXGIFormat); + unsigned int srcPixelSize = srcSizeInfo.pixelBytes; + unsigned int copyOffset = 0; + unsigned int copySize = srcPixelSize; + auto destDXGIFormat = dest.getFormat(); + const auto &destSizeInfo = d3d11::GetDXGIFormatSizeInfo(destDXGIFormat); + unsigned int destPixelSize = destSizeInfo.pixelBytes; + + ASSERT(srcDXGIFormat == destDXGIFormat || destDXGIFormat == DXGI_FORMAT_R32_TYPELESS); - auto format = source.getFormat(); - const auto &sizeInfo = d3d11::GetDXGIFormatSizeInfo(format); - unsigned int pixelSize = sizeInfo.pixelBytes; - unsigned int copyOffset = 0; - unsigned int copySize = pixelSize; if (stencilOnly) { - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + const auto &srcFormat = source.getFormatSet().format; // Stencil channel should be right after the depth channel. Some views to depth/stencil // resources have red channel for depth, in which case the depth channel bit width is in // redBits. - ASSERT((dxgiFormatInfo.redBits != 0) != (dxgiFormatInfo.depthBits != 0)); - GLuint depthBits = dxgiFormatInfo.redBits + dxgiFormatInfo.depthBits; + ASSERT((srcFormat.redBits != 0) != (srcFormat.depthBits != 0)); + GLuint depthBits = srcFormat.redBits + srcFormat.depthBits; // Known formats have either 24 or 32 bits of depth. ASSERT(depthBits == 24 || depthBits == 32); copyOffset = depthBits / 8; @@ -1221,26 +1487,41 @@ gl::Error Blit11::copyDepthStencilImpl(const TextureHelper11 &source, copySize = 1; } + if (srcDXGIFormat != destDXGIFormat) + { + if (srcDXGIFormat == DXGI_FORMAT_R24G8_TYPELESS) + { + ASSERT(sourceArea == destArea && sourceSize == destSize && scissor == nullptr); + return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, copyOffset, + copyOffset, copySize, srcPixelSize, destPixelSize, + BlitD24S8ToD32F); + } + ASSERT(srcDXGIFormat == DXGI_FORMAT_R32G8X24_TYPELESS); + return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, copyOffset, copyOffset, + copySize, srcPixelSize, destPixelSize, BlitD32FS8ToD32F); + } + return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource, - destArea, destSize, scissor, copyOffset, copyOffset, copySize, pixelSize, - pixelSize, StretchedBlitNearest); + destArea, destSize, scissor, copyOffset, copyOffset, copySize, + srcPixelSize, destPixelSize, StretchedBlitNearest); } -gl::Error Blit11::copyAndConvert(const TextureHelper11 &source, - unsigned int sourceSubresource, - const gl::Box &sourceArea, - const gl::Extents &sourceSize, - const TextureHelper11 &dest, - unsigned int destSubresource, - const gl::Box &destArea, - const gl::Extents &destSize, - const gl::Rectangle *scissor, - size_t readOffset, - size_t writeOffset, - size_t copySize, - size_t srcPixelStride, - size_t destPixelStride, - BlitConvertFunction *convertFunction) +gl::Error Blit11::copyAndConvertImpl(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &destStaging, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction) { ANGLE_TRY(initResources()); @@ -1248,24 +1529,13 @@ gl::Error Blit11::copyAndConvert(const TextureHelper11 &source, ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); TextureHelper11 sourceStaging; - ANGLE_TRY_RESULT(CreateStagingTexture(GL_TEXTURE_2D, source.getANGLEFormat(), sourceSize, + ANGLE_TRY_RESULT(CreateStagingTexture(GL_TEXTURE_2D, source.getFormatSet(), sourceSize, StagingAccess::READ, device), sourceStaging); deviceContext->CopySubresourceRegion(sourceStaging.getResource(), 0, 0, 0, 0, source.getResource(), sourceSubresource, nullptr); - // HACK: Create the destination staging buffer as a read/write texture so - // ID3D11DevicContext::UpdateSubresource can be called - // using it's mapped data as a source - TextureHelper11 destStaging; - ANGLE_TRY_RESULT(CreateStagingTexture(GL_TEXTURE_2D, dest.getANGLEFormat(), destSize, - StagingAccess::READ_WRITE, device), - destStaging); - - deviceContext->CopySubresourceRegion(destStaging.getResource(), 0, 0, 0, 0, dest.getResource(), - destSubresource, nullptr); - D3D11_MAPPED_SUBRESOURCE sourceMapping; HRESULT result = deviceContext->Map(sourceStaging.getResource(), 0, D3D11_MAP_READ, 0, &sourceMapping); @@ -1302,21 +1572,62 @@ gl::Error Blit11::copyAndConvert(const TextureHelper11 &source, destPixelStride, static_cast<const uint8_t *>(sourceMapping.pData), static_cast<uint8_t *>(destMapping.pData)); - // HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to - // ID3D11DevicContext::CopySubresourceRegion - // according to MSDN. - deviceContext->UpdateSubresource(dest.getResource(), destSubresource, nullptr, - destMapping.pData, destMapping.RowPitch, - destMapping.DepthPitch); - deviceContext->Unmap(sourceStaging.getResource(), 0); deviceContext->Unmap(destStaging.getResource(), 0); - // TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR - // timeout on some - // systems when called repeatedly. - // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, - // nullptr); + return gl::NoError(); +} + +gl::Error Blit11::copyAndConvert(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction) +{ + ANGLE_TRY(initResources()); + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // HACK: Create the destination staging buffer as a read/write texture so + // ID3D11DevicContext::UpdateSubresource can be called + // using it's mapped data as a source + TextureHelper11 destStaging; + ANGLE_TRY_RESULT(CreateStagingTexture(GL_TEXTURE_2D, dest.getFormatSet(), destSize, + StagingAccess::READ_WRITE, device), + destStaging); + + deviceContext->CopySubresourceRegion(destStaging.getResource(), 0, 0, 0, 0, dest.getResource(), + destSubresource, nullptr); + + copyAndConvertImpl(source, sourceSubresource, sourceArea, sourceSize, destStaging, destArea, + destSize, scissor, readOffset, writeOffset, copySize, srcPixelStride, + destPixelStride, convertFunction); + + // Work around timeouts/TDRs in older NVIDIA drivers. + if (mRenderer->getWorkarounds().depthStencilBlitExtraCopy) + { + D3D11_MAPPED_SUBRESOURCE mapped; + deviceContext->Map(destStaging.getResource(), 0, D3D11_MAP_READ, 0, &mapped); + deviceContext->UpdateSubresource(dest.getResource(), destSubresource, nullptr, mapped.pData, + mapped.RowPitch, mapped.DepthPitch); + deviceContext->Unmap(destStaging.getResource(), 0); + } + else + { + deviceContext->CopySubresourceRegion(dest.getResource(), destSubresource, 0, 0, 0, + destStaging.getResource(), 0, nullptr); + } return gl::NoError(); } @@ -1366,10 +1677,13 @@ void Blit11::clearShaderMap() gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, ShaderDimension dimension, const Shader **shader) { - BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, dimension); + BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha, dimension); if (blitShaderType == BLITSHADER_INVALID) { @@ -1394,16 +1708,46 @@ gl::Error Blit11::getBlitShader(GLenum destFormat, blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader")); break; + case BLITSHADER_2D_RGBAF_PREMULTIPLY: + addBlitShaderToMap(blitShaderType, SHADER_2D, + d3d11::CompilePS(device, g_PS_PassthroughRGBAPremultiply2D, + "Blit11 2D RGBA premultiply pixel shader")); + break; + case BLITSHADER_2D_RGBAF_UNMULTIPLY: + addBlitShaderToMap(blitShaderType, SHADER_2D, + d3d11::CompilePS(device, g_PS_PassthroughRGBAUnmultiply2D, + "Blit11 2D RGBA unmultiply pixel shader")); + break; case BLITSHADER_2D_BGRAF: addBlitShaderToMap( blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader")); break; + case BLITSHADER_2D_BGRAF_PREMULTIPLY: + addBlitShaderToMap(blitShaderType, SHADER_2D, + d3d11::CompilePS(device, g_PS_PassthroughRGBAPremultiply2D, + "Blit11 2D BGRA premultiply pixel shader")); + break; + case BLITSHADER_2D_BGRAF_UNMULTIPLY: + addBlitShaderToMap(blitShaderType, SHADER_2D, + d3d11::CompilePS(device, g_PS_PassthroughRGBAUnmultiply2D, + "Blit11 2D BGRA unmultiply pixel shader")); + break; case BLITSHADER_2D_RGBF: addBlitShaderToMap( blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader")); break; + case BLITSHADER_2D_RGBF_PREMULTIPLY: + addBlitShaderToMap(blitShaderType, SHADER_2D, + d3d11::CompilePS(device, g_PS_PassthroughRGBPremultiply2D, + "Blit11 2D RGB premultiply pixel shader")); + break; + case BLITSHADER_2D_RGBF_UNMULTIPLY: + addBlitShaderToMap(blitShaderType, SHADER_2D, + d3d11::CompilePS(device, g_PS_PassthroughRGBUnmultiply2D, + "Blit11 2D RGB unmultiply pixel shader")); + break; case BLITSHADER_2D_RGF: addBlitShaderToMap( blitShaderType, SHADER_2D, @@ -1656,13 +2000,253 @@ gl::Error Blit11::getSwizzleShader(GLenum type, return gl::NoError(); } -gl::ErrorOrResult<TextureHelper11> Blit11::resolveDepthStencil(RenderTarget11 *dsRenderTarget, - bool resolveDepth, - bool resolveStencil) +gl::ErrorOrResult<TextureHelper11> Blit11::resolveDepth(RenderTarget11 *depth) { - ASSERT(resolveDepth || resolveStencil); - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, - "Multisample depth stencil resolve not implemented yet."); + // Multisampled depth stencil SRVs are not available in feature level 10.0 + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0) + { + return gl::Error(GL_INVALID_OPERATION, + "Resolving multisampled depth stencil textures is not supported in " + "feature level 10.0."); + } + + const auto &extents = depth->getExtents(); + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + ANGLE_TRY(initResolveDepthStencil(extents)); + + // Notify the Renderer that all state should be invalidated. + mRenderer->markAllStateDirty(); + + // Apply the necessary state changes to the D3D11 immediate device context. + context->IASetInputLayout(nullptr); + context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + context->VSSetShader(mResolveDepthStencilVS.resolve(device), nullptr, 0); + context->GSSetShader(nullptr, nullptr, 0); + context->RSSetState(nullptr); + context->OMSetDepthStencilState(nullptr, 0xFFFFFFFF); + context->OMSetRenderTargets(1, &mResolvedDepthStencilRTView, nullptr); + context->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = static_cast<FLOAT>(extents.width); + viewport.Height = static_cast<FLOAT>(extents.height); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + context->RSSetViewports(1, &viewport); + + ID3D11ShaderResourceView *pixelViews[] = {depth->getShaderResourceView()}; + + context->PSSetShaderResources(0, 1, pixelViews); + + context->PSSetShader(mResolveDepthPS.resolve(device), nullptr, 0); + + // Trigger the blit on the GPU. + context->Draw(6, 0); + + gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1); + + const auto ©Function = GetCopyDepthStencilFunction(depth->getInternalFormat()); + const auto &dsFormatSet = depth->getFormatSet(); + const auto &dsDxgiInfo = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat); + + ID3D11Texture2D *destTex = nullptr; + + D3D11_TEXTURE2D_DESC destDesc; + destDesc.Width = extents.width; + destDesc.Height = extents.height; + destDesc.MipLevels = 1; + destDesc.ArraySize = 1; + destDesc.Format = dsFormatSet.texFormat; + destDesc.SampleDesc.Count = 1; + destDesc.SampleDesc.Quality = 0; + destDesc.Usage = D3D11_USAGE_DEFAULT; + destDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + destDesc.CPUAccessFlags = 0; + destDesc.MiscFlags = 0; + + HRESULT hr = device->CreateTexture2D(&destDesc, nullptr, &destTex); + if (FAILED(hr)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Error creating depth resolve dest texture."); + } + d3d11::SetDebugName(destTex, "resolveDepthDest"); + + TextureHelper11 dest = TextureHelper11::MakeAndPossess2D(destTex, depth->getFormatSet()); + ANGLE_TRY(copyAndConvert(mResolvedDepthStencil, 0, copyBox, extents, dest, 0, copyBox, extents, + nullptr, 0, 0, 0, 8, dsDxgiInfo.pixelBytes, copyFunction)); + return dest; +} + +gl::Error Blit11::initResolveDepthStencil(const gl::Extents &extents) +{ + // Check if we need to recreate depth stencil view + if (mResolvedDepthStencil.valid() && extents == mResolvedDepthStencil.getExtents()) + { + return gl::NoError(); + } + + if (mResolvedDepthStencil.valid()) + { + releaseResolveDepthStencilResources(); + } + + const auto &formatSet = d3d11::Format::Get(GL_RG32F, mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC textureDesc; + textureDesc.Width = extents.width; + textureDesc.Height = extents.height; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = formatSet.texFormat; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = 0; + + ID3D11Device *device = mRenderer->getDevice(); + + ID3D11Texture2D *resolvedDepthStencil = nullptr; + HRESULT hr = device->CreateTexture2D(&textureDesc, nullptr, &resolvedDepthStencil); + if (FAILED(hr)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate resolved depth stencil texture"); + } + d3d11::SetDebugName(resolvedDepthStencil, "Blit11::mResolvedDepthStencil"); + + ASSERT(mResolvedDepthStencilRTView == nullptr); + hr = + device->CreateRenderTargetView(resolvedDepthStencil, nullptr, &mResolvedDepthStencilRTView); + if (FAILED(hr)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to allocate Blit11::mResolvedDepthStencilRTView"); + } + d3d11::SetDebugName(mResolvedDepthStencilRTView, "Blit11::mResolvedDepthStencilRTView"); + + mResolvedDepthStencil = TextureHelper11::MakeAndPossess2D(resolvedDepthStencil, formatSet); + + return gl::NoError(); +} + +gl::ErrorOrResult<TextureHelper11> Blit11::resolveStencil(RenderTarget11 *depthStencil, + bool alsoDepth) +{ + // Multisampled depth stencil SRVs are not available in feature level 10.0 + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0) + { + return gl::Error(GL_INVALID_OPERATION, + "Resolving multisampled depth stencil textures is not supported in " + "feature level 10.0."); + } + + const auto &extents = depthStencil->getExtents(); + + ANGLE_TRY(initResolveDepthStencil(extents)); + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + ID3D11Resource *stencilResource = depthStencil->getTexture(); + + // Check if we need to re-create the stencil SRV. + if (mStencilSRV) + { + ID3D11Resource *priorResource = nullptr; + mStencilSRV->GetResource(&priorResource); + + if (stencilResource != priorResource) + { + SafeRelease(mStencilSRV); + } + } + + if (!mStencilSRV) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc; + srViewDesc.Format = GetStencilSRVFormat(depthStencil->getFormatSet()); + srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + + HRESULT hr = device->CreateShaderResourceView(stencilResource, &srViewDesc, &mStencilSRV); + if (FAILED(hr)) + { + return gl::Error(GL_OUT_OF_MEMORY, "Error creating Blit11 stencil SRV"); + } + d3d11::SetDebugName(mStencilSRV, "Blit11::mStencilSRV"); + } + + // Notify the Renderer that all state should be invalidated. + mRenderer->markAllStateDirty(); + + // Apply the necessary state changes to the D3D11 immediate device context. + context->IASetInputLayout(nullptr); + context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + context->VSSetShader(mResolveDepthStencilVS.resolve(device), nullptr, 0); + context->GSSetShader(nullptr, nullptr, 0); + context->RSSetState(nullptr); + context->OMSetDepthStencilState(nullptr, 0xFFFFFFFF); + context->OMSetRenderTargets(1, &mResolvedDepthStencilRTView, nullptr); + context->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = static_cast<FLOAT>(extents.width); + viewport.Height = static_cast<FLOAT>(extents.height); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + context->RSSetViewports(1, &viewport); + + ID3D11ShaderResourceView *pixelViews[] = { + depthStencil->getShaderResourceView(), mStencilSRV, + }; + + context->PSSetShaderResources(0, 2, pixelViews); + + // Resolving the depth buffer works by sampling the depth in the shader using a SRV, then + // writing to the resolved depth buffer using SV_Depth. We can't use this method for stencil + // because SV_StencilRef isn't supported until HLSL 5.1/D3D11.3. + if (alsoDepth) + { + context->PSSetShader(mResolveDepthStencilPS.resolve(device), nullptr, 0); + } + else + { + context->PSSetShader(mResolveStencilPS.resolve(device), nullptr, 0); + } + + // Trigger the blit on the GPU. + context->Draw(6, 0); + + gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1); + + TextureHelper11 dest; + ANGLE_TRY_RESULT(CreateStagingTexture(GL_TEXTURE_2D, depthStencil->getFormatSet(), extents, + StagingAccess::READ_WRITE, device), + dest); + + const auto ©Function = GetCopyDepthStencilFunction(depthStencil->getInternalFormat()); + const auto &dsFormatSet = depthStencil->getFormatSet(); + const auto &dsDxgiInfo = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat); + + ANGLE_TRY(copyAndConvertImpl(mResolvedDepthStencil, 0, copyBox, extents, dest, copyBox, extents, + nullptr, 0, 0, 0, 8u, dsDxgiInfo.pixelBytes, copyFunction)); + + // Return the resolved depth texture, which the caller must Release. + return dest; } + +void Blit11::releaseResolveDepthStencilResources() +{ + SafeRelease(mStencilSRV); + SafeRelease(mResolvedDepthStencilRTView); +} + } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h index ff042b8a134..e61f096c69d 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h @@ -40,7 +40,9 @@ class Blit11 : angle::NonCopyable const gl::Rectangle *scissor, GLenum destFormat, GLenum filter, - bool maskOffAlpha); + bool maskOffAlpha, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); gl::Error copyStencil(const TextureHelper11 &source, unsigned int sourceSubresource, @@ -70,17 +72,37 @@ class Blit11 : angle::NonCopyable const gl::Extents &destSize, const gl::Rectangle *scissor); - gl::ErrorOrResult<TextureHelper11> resolveDepthStencil(RenderTarget11 *dsRenderTarget, - bool resolveDepth, - bool resolveStencil); + gl::ErrorOrResult<TextureHelper11> resolveDepth(RenderTarget11 *depth); + + gl::ErrorOrResult<TextureHelper11> resolveStencil(RenderTarget11 *depthStencil, bool alsoDepth); + + using BlitConvertFunction = void(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clipRect, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData); private: enum BlitShaderType { BLITSHADER_INVALID, BLITSHADER_2D_RGBAF, + BLITSHADER_2D_RGBAF_PREMULTIPLY, + BLITSHADER_2D_RGBAF_UNMULTIPLY, BLITSHADER_2D_BGRAF, + BLITSHADER_2D_BGRAF_PREMULTIPLY, + BLITSHADER_2D_BGRAF_UNMULTIPLY, BLITSHADER_2D_RGBF, + BLITSHADER_2D_RGBF_PREMULTIPLY, + BLITSHADER_2D_RGBF_UNMULTIPLY, BLITSHADER_2D_RGF, BLITSHADER_2D_RF, BLITSHADER_2D_ALPHA, @@ -165,23 +187,11 @@ class Blit11 : angle::NonCopyable static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, ShaderDimension dimension); static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality); - typedef void BlitConvertFunction(const gl::Box &sourceArea, - const gl::Box &destArea, - const gl::Rectangle &clipRect, - const gl::Extents &sourceSize, - unsigned int sourceRowPitch, - unsigned int destRowPitch, - ptrdiff_t readOffset, - ptrdiff_t writeOffset, - size_t copySize, - size_t srcPixelStride, - size_t destPixelStride, - const uint8_t *sourceData, - uint8_t *destData); - gl::Error copyDepthStencilImpl(const TextureHelper11 &source, unsigned int sourceSubresource, const gl::Box &sourceArea, @@ -193,6 +203,21 @@ class Blit11 : angle::NonCopyable const gl::Rectangle *scissor, bool stencilOnly); + gl::Error copyAndConvertImpl(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &destStaging, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction); + gl::Error copyAndConvert(const TextureHelper11 &source, unsigned int sourceSubresource, const gl::Box &sourceArea, @@ -215,6 +240,8 @@ class Blit11 : angle::NonCopyable gl::Error getBlitShader(GLenum destFormat, bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, ShaderDimension dimension, const Shader **shaderOut); gl::Error getSwizzleShader(GLenum type, @@ -226,6 +253,8 @@ class Blit11 : angle::NonCopyable ID3D11PixelShader *ps); void clearShaderMap(); + void releaseResolveDepthStencilResources(); + gl::Error initResolveDepthStencil(const gl::Extents &extents); Renderer11 *mRenderer; @@ -251,6 +280,14 @@ class Blit11 : angle::NonCopyable d3d11::LazyBlendState mAlphaMaskBlendState; ID3D11Buffer *mSwizzleCB; + + d3d11::LazyShader<ID3D11VertexShader> mResolveDepthStencilVS; + d3d11::LazyShader<ID3D11PixelShader> mResolveDepthPS; + d3d11::LazyShader<ID3D11PixelShader> mResolveDepthStencilPS; + d3d11::LazyShader<ID3D11PixelShader> mResolveStencilPS; + ID3D11ShaderResourceView *mStencilSRV; + TextureHelper11 mResolvedDepthStencil; + ID3D11RenderTargetView *mResolvedDepthStencilRTView; }; } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp index 723eef0fad4..731680dc8e7 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp @@ -43,7 +43,7 @@ enum class CopyResult namespace gl_d3d11 { -D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) +D3D11_MAP GetD3DMapTypeFromBits(BufferUsage usage, GLbitfield access) { bool readBit = ((access & GL_MAP_READ_BIT) != 0); bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0); @@ -59,7 +59,8 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) } else if (writeBit && !readBit) { - return D3D11_MAP_WRITE; + // Special case for uniform storage - we only allow full buffer updates. + return usage == BUFFER_USAGE_UNIFORM ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE; } else if (writeBit && readBit) { @@ -88,7 +89,7 @@ class Buffer11::BufferStorage : angle::NonCopyable size_t getSize() const { return mBufferSize; } void setDataRevision(DataRevision rev) { mRevision = rev; } - virtual bool isMappable() const = 0; + virtual bool isMappable(GLbitfield access) const = 0; virtual gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source, size_t sourceOffset, @@ -123,7 +124,7 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage const angle::BroadcastChannel *onStorageChanged); ~NativeStorage() override; - bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; } + bool isMappable(GLbitfield access) const override; ID3D11Buffer *getNativeStorage() const { return mNativeStorage; } gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source, @@ -138,14 +139,18 @@ class Buffer11::NativeStorage : public Buffer11::BufferStorage uint8_t **mapPointerOut) override; void unmap() override; + gl::ErrorOrResult<ID3D11ShaderResourceView *> getSRVForFormat(DXGI_FORMAT srvFormat); + private: - static void fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, + static void FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize); + void clearSRVs(); ID3D11Buffer *mNativeStorage; const angle::BroadcastChannel *mOnStorageChanged; + std::map<DXGI_FORMAT, ID3D11ShaderResourceView *> mBufferResourceViews; }; // A emulated indexed buffer storage represents an underlying D3D11 buffer for data @@ -157,7 +162,7 @@ class Buffer11::EmulatedIndexedStorage : public Buffer11::BufferStorage EmulatedIndexedStorage(Renderer11 *renderer); ~EmulatedIndexedStorage() override; - bool isMappable() const override { return true; } + bool isMappable(GLbitfield access) const override { return true; } gl::ErrorOrResult<ID3D11Buffer *> getNativeStorage(SourceIndexData *indexInfo, const TranslatedAttribute &attribute, @@ -190,7 +195,7 @@ class Buffer11::PackStorage : public Buffer11::BufferStorage explicit PackStorage(Renderer11 *renderer); ~PackStorage() override; - bool isMappable() const override { return true; } + bool isMappable(GLbitfield access) const override { return true; } gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source, size_t sourceOffset, size_t size, @@ -225,7 +230,7 @@ class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage explicit SystemMemoryStorage(Renderer11 *renderer); ~SystemMemoryStorage() override {} - bool isMappable() const override { return true; } + bool isMappable(GLbitfield access) const override { return true; } gl::ErrorOrResult<CopyResult> copyFromStorage(BufferStorage *source, size_t sourceOffset, size_t size, @@ -249,11 +254,11 @@ Buffer11::Buffer11(Renderer11 *renderer) mRenderer(renderer), mSize(0), mMappedStorage(nullptr), - mBufferStorages(BUFFER_USAGE_COUNT, nullptr), + mBufferStorages({}), + mDeallocThresholds({}), + mIdleness({}), mConstantBufferStorageAdditionalSize(0), - mMaxConstantBufferLruCount(0), - mReadUsageCount(0), - mSystemMemoryDeallocThreshold(0) + mMaxConstantBufferLruCount(0) { } @@ -272,10 +277,10 @@ Buffer11::~Buffer11() mRenderer->onBufferDelete(this); } -gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) +gl::Error Buffer11::setData(GLenum target, const void *data, size_t size, GLenum usage) { updateD3DBufferUsage(usage); - ANGLE_TRY(setSubData(data, size, 0)); + ANGLE_TRY(setSubData(target, data, size, 0)); return gl::NoError(); } @@ -284,8 +289,6 @@ gl::Error Buffer11::getData(const uint8_t **outData) SystemMemoryStorage *systemMemoryStorage = nullptr; ANGLE_TRY_RESULT(getSystemMemoryStorage(), systemMemoryStorage); - mReadUsageCount = 0; - ASSERT(systemMemoryStorage->getSize() >= mSize); *outData = systemMemoryStorage->getSystemCopy()->data(); @@ -299,16 +302,20 @@ gl::ErrorOrResult<Buffer11::SystemMemoryStorage *> Buffer11::getSystemMemoryStor return GetAs<SystemMemoryStorage>(storage); } -gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) +gl::Error Buffer11::setSubData(GLenum target, const void *data, size_t size, size_t offset) { size_t requiredSize = size + offset; if (data && size > 0) { // Use system memory storage for dynamic buffers. - + // Try using a constant storage for constant buffers BufferStorage *writeBuffer = nullptr; - if (supportsDirectBinding()) + if (target == GL_UNIFORM_BUFFER && offset == 0 && size >= mSize) + { + ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_UNIFORM), writeBuffer); + } + else if (supportsDirectBinding()) { ANGLE_TRY_RESULT(getStagingStorage(), writeBuffer); } @@ -363,11 +370,12 @@ gl::Error Buffer11::copySubData(BufferImpl *source, // If copying to/from a pixel pack buffer, we must have a staging or // pack buffer partner, because other native buffers can't be mapped - if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable()) + if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable(GL_MAP_READ_BIT)) { ANGLE_TRY_RESULT(sourceBuffer->getStagingStorage(), copySource); } - else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable()) + else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && + !copyDest->isMappable(GL_MAP_WRITE_BIT)) { ANGLE_TRY_RESULT(getStagingStorage(), copyDest); } @@ -474,50 +482,65 @@ gl::Error Buffer11::markTransformFeedbackUsage() return gl::NoError(); } -void Buffer11::updateSystemMemoryDeallocThreshold() +void Buffer11::updateDeallocThreshold(BufferUsage usage) { // The following strategy was tuned on the Oort online benchmark (http://oortonline.gl/) // as well as a custom microbenchmark (IndexConversionPerfTest.Run/index_range_d3d11) - // First readback: 8 unmodified uses before we free system memory. + // First readback: 8 unmodified uses before we free buffer memory. // After that, double the threshold each time until we reach the max. - if (mSystemMemoryDeallocThreshold == 0) + if (mDeallocThresholds[usage] == 0) { - mSystemMemoryDeallocThreshold = 8; + mDeallocThresholds[usage] = 8; } - else if (mSystemMemoryDeallocThreshold < std::numeric_limits<unsigned int>::max() / 2u) + else if (mDeallocThresholds[usage] < std::numeric_limits<unsigned int>::max() / 2u) { - mSystemMemoryDeallocThreshold *= 2u; + mDeallocThresholds[usage] *= 2u; } else { - mSystemMemoryDeallocThreshold = std::numeric_limits<unsigned int>::max(); + mDeallocThresholds[usage] = std::numeric_limits<unsigned int>::max(); } } -gl::Error Buffer11::markBufferUsage() +// Free the storage if we decide it isn't being used very often. +gl::Error Buffer11::checkForDeallocation(BufferUsage usage) { - mReadUsageCount++; + mIdleness[usage]++; - // Free the system memory storage if we decide it isn't being used very often. - BufferStorage *&sysMemStorage = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY]; - if (sysMemStorage != nullptr && mReadUsageCount > mSystemMemoryDeallocThreshold) + BufferStorage *&storage = mBufferStorages[usage]; + if (storage != nullptr && mIdleness[usage] > mDeallocThresholds[usage]) { BufferStorage *latestStorage = nullptr; ANGLE_TRY_RESULT(getLatestBufferStorage(), latestStorage); - if (latestStorage != sysMemStorage) + if (latestStorage != storage) { - SafeDelete(sysMemStorage); + SafeDelete(storage); } } return gl::NoError(); } -gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getBuffer(BufferUsage usage) +gl::Error Buffer11::markBufferUsage(BufferUsage usage) { - ANGLE_TRY(markBufferUsage()); + mIdleness[usage] = 0; + + if (usage != BUFFER_USAGE_SYSTEM_MEMORY) + { + ANGLE_TRY(checkForDeallocation(BUFFER_USAGE_SYSTEM_MEMORY)); + } + if (usage != BUFFER_USAGE_STAGING) + { + ANGLE_TRY(checkForDeallocation(BUFFER_USAGE_STAGING)); + } + + return gl::NoError(); +} + +gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getBuffer(BufferUsage usage) +{ BufferStorage *storage = nullptr; ANGLE_TRY_RESULT(getBufferStorage(usage), storage); return GetAs<NativeStorage>(storage)->getNativeStorage(); @@ -530,8 +553,6 @@ gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getEmulatedIndexedBuffer( { ASSERT(indexInfo); - ANGLE_TRY(markBufferUsage()); - BufferStorage *untypedStorage = nullptr; ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_EMULATED_INDEXED_VERTEX), untypedStorage); @@ -546,11 +567,9 @@ gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getEmulatedIndexedBuffer( gl::ErrorOrResult<ID3D11Buffer *> Buffer11::getConstantBufferRange(GLintptr offset, GLsizeiptr size) { - ANGLE_TRY(markBufferUsage()); - BufferStorage *bufferStorage = nullptr; - if (offset == 0) + if (offset == 0 || mRenderer->getRenderer11DeviceCaps().supportsConstantBufferOffsets) { ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_UNIFORM), bufferStorage); } @@ -566,42 +585,8 @@ gl::ErrorOrResult<ID3D11ShaderResourceView *> Buffer11::getSRV(DXGI_FORMAT srvFo { BufferStorage *storage = nullptr; ANGLE_TRY_RESULT(getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK), storage); - ID3D11Buffer *buffer = GetAs<NativeStorage>(storage)->getNativeStorage(); - - auto bufferSRVIt = mBufferResourceViews.find(srvFormat); - - if (bufferSRVIt != mBufferResourceViews.end()) - { - if (bufferSRVIt->second.first == buffer) - { - return bufferSRVIt->second.second; - } - else - { - // The underlying buffer has changed since the SRV was created: recreate the SRV. - SafeRelease(bufferSRVIt->second.second); - } - } - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11ShaderResourceView *bufferSRV = nullptr; - - const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(srvFormat); - - D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; - bufferSRVDesc.Buffer.ElementOffset = 0; - bufferSRVDesc.Buffer.ElementWidth = - static_cast<unsigned int>(mSize) / dxgiFormatInfo.pixelBytes; - bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - bufferSRVDesc.Format = srvFormat; - - HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); - - mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV); - - return bufferSRV; + NativeStorage *nativeStorage = GetAs<NativeStorage>(storage); + return nativeStorage->getSRVForFormat(srvFormat); } gl::Error Buffer11::packPixels(const gl::FramebufferAttachment &readAttachment, @@ -650,21 +635,20 @@ gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getBufferStorage(BufferUs } ANGLE_TRY(updateBufferStorage(newStorage, 0, mSize)); + ANGLE_TRY(markBufferUsage(usage)); return newStorage; } Buffer11::BufferStorage *Buffer11::allocateStorage(BufferUsage usage) { + updateDeallocThreshold(usage); switch (usage) { case BUFFER_USAGE_PIXEL_PACK: return new PackStorage(mRenderer); case BUFFER_USAGE_SYSTEM_MEMORY: - { - updateSystemMemoryDeallocThreshold(); return new SystemMemoryStorage(mRenderer); - } case BUFFER_USAGE_EMULATED_INDEXED_VERTEX: return new EmulatedIndexedStorage(mRenderer); case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: @@ -729,6 +713,7 @@ gl::ErrorOrResult<Buffer11::BufferStorage *> Buffer11::getConstantBufferRangeSto } ANGLE_TRY(updateBufferStorage(newStorage, offset, size)); + ANGLE_TRY(markBufferUsage(BUFFER_USAGE_UNIFORM)); return newStorage; } @@ -746,7 +731,7 @@ gl::Error Buffer11::updateBufferStorage(BufferStorage *storage, // data directly. If we're already using a staging buffer we're fine. if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING && storage->getUsage() != BUFFER_USAGE_STAGING && - (!latestBuffer->isMappable() || !storage->isMappable())) + (!latestBuffer->isMappable(GL_MAP_READ_BIT) || !storage->isMappable(GL_MAP_WRITE_BIT))) { NativeStorage *stagingBuffer = nullptr; ANGLE_TRY_RESULT(getStagingStorage(), stagingBuffer); @@ -845,6 +830,8 @@ angle::BroadcastChannel *Buffer11::getDirectBroadcastChannel() return &mDirectBroadcastChannel; } +// Buffer11::BufferStorage implementation + Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage) : mRenderer(renderer), mRevision(0), mUsage(usage), mBufferSize(0) { @@ -852,7 +839,7 @@ Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage) gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, size_t size) { - ASSERT(isMappable()); + ASSERT(isMappable(GL_MAP_WRITE_BIT)); uint8_t *writePointer = nullptr; ANGLE_TRY(map(offset, size, GL_MAP_WRITE_BIT, &writePointer)); @@ -864,6 +851,8 @@ gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, s return gl::NoError(); } +// Buffer11::NativeStorage implementation + Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, BufferUsage usage, const angle::BroadcastChannel *onStorageChanged) @@ -874,6 +863,18 @@ Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, Buffer11::NativeStorage::~NativeStorage() { SafeRelease(mNativeStorage); + clearSRVs(); +} + +bool Buffer11::NativeStorage::isMappable(GLbitfield access) const +{ + if ((access & GL_MAP_READ_BIT) != 0) + { + // Read is more exclusive than write mappability. + return (mUsage == BUFFER_USAGE_STAGING); + } + ASSERT((access & GL_MAP_WRITE_BIT) != 0); + return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_UNIFORM); } // Returns true if it recreates the direct buffer @@ -888,45 +889,42 @@ gl::ErrorOrResult<CopyResult> Buffer11::NativeStorage::copyFromStorage(BufferSto bool createBuffer = !mNativeStorage || mBufferSize < requiredSize; // (Re)initialize D3D buffer if needed + bool preserveData = (destOffset > 0); if (createBuffer) { - bool preserveData = (destOffset > 0); resize(requiredSize, preserveData); } + size_t clampedSize = size; + if (mUsage == BUFFER_USAGE_UNIFORM) + { + clampedSize = std::min(clampedSize, mBufferSize - destOffset); + } + if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK || source->getUsage() == BUFFER_USAGE_SYSTEM_MEMORY) { - ASSERT(source->isMappable()); + ASSERT(source->isMappable(GL_MAP_READ_BIT) && isMappable(GL_MAP_WRITE_BIT)); - uint8_t *sourcePointer = nullptr; - ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourcePointer)); + // Uniform buffers must be mapped with write/discard. + ASSERT(!(preserveData && mUsage == BUFFER_USAGE_UNIFORM)); - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource); - ASSERT(SUCCEEDED(hr)); - if (FAILED(hr)) - { - source->unmap(); - return gl::Error( - GL_OUT_OF_MEMORY, - "Failed to map native storage in Buffer11::NativeStorage::copyFromStorage"); - } + uint8_t *sourcePointer = nullptr; + ANGLE_TRY(source->map(sourceOffset, clampedSize, GL_MAP_READ_BIT, &sourcePointer)); - uint8_t *destPointer = static_cast<uint8_t *>(mappedResource.pData) + destOffset; + uint8_t *destPointer = nullptr; + ANGLE_TRY(map(destOffset, clampedSize, GL_MAP_WRITE_BIT, &destPointer)); - // Offset bounds are validated at the API layer - ASSERT(sourceOffset + size <= destOffset + mBufferSize); - memcpy(destPointer, sourcePointer, size); + memcpy(destPointer, sourcePointer, clampedSize); - context->Unmap(mNativeStorage, 0); + unmap(); source->unmap(); } else { D3D11_BOX srcBox; srcBox.left = static_cast<unsigned int>(sourceOffset); - srcBox.right = static_cast<unsigned int>(sourceOffset + size); + srcBox.right = static_cast<unsigned int>(sourceOffset + clampedSize); srcBox.top = 0; srcBox.bottom = 1; srcBox.front = 0; @@ -947,7 +945,7 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) ID3D11DeviceContext *context = mRenderer->getDeviceContext(); D3D11_BUFFER_DESC bufferDesc; - fillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast<unsigned int>(size)); + FillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast<unsigned int>(size)); ID3D11Buffer *newBuffer; HRESULT result = device->CreateBuffer(&bufferDesc, nullptr, &newBuffer); @@ -982,6 +980,9 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) mBufferSize = bufferDesc.ByteWidth; + // Free the SRVs. + clearSRVs(); + // Notify that the storage has changed. if (mOnStorageChanged) { @@ -991,7 +992,8 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) return gl::NoError(); } -void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, +// static +void Buffer11::NativeStorage::FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize) @@ -1040,6 +1042,9 @@ void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, // Constant buffers must be of a limited size, and aligned to 16 byte boundaries // For our purposes we ignore any buffer data past the maximum constant buffer size bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u); + + // Note: it seems that D3D11 allows larger buffers on some platforms, but not all. + // (Windows 10 seems to allow larger constant buffers, but not Windows 7) bufferDesc->ByteWidth = std::min<UINT>(bufferDesc->ByteWidth, static_cast<UINT>(renderer->getNativeCaps().maxUniformBlockSize)); @@ -1055,11 +1060,11 @@ gl::Error Buffer11::NativeStorage::map(size_t offset, GLbitfield access, uint8_t **mapPointerOut) { - ASSERT(mUsage == BUFFER_USAGE_STAGING); + ASSERT(isMappable(access)); D3D11_MAPPED_SUBRESOURCE mappedResource; ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access); + D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(mUsage, access); UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); HRESULT result = context->Map(mNativeStorage, 0, d3dMapType, d3dMapFlag, &mappedResource); @@ -1076,11 +1081,56 @@ gl::Error Buffer11::NativeStorage::map(size_t offset, void Buffer11::NativeStorage::unmap() { - ASSERT(mUsage == BUFFER_USAGE_STAGING); + ASSERT(isMappable(GL_MAP_WRITE_BIT) || isMappable(GL_MAP_READ_BIT)); ID3D11DeviceContext *context = mRenderer->getDeviceContext(); context->Unmap(mNativeStorage, 0); } +gl::ErrorOrResult<ID3D11ShaderResourceView *> Buffer11::NativeStorage::getSRVForFormat( + DXGI_FORMAT srvFormat) +{ + auto bufferSRVIt = mBufferResourceViews.find(srvFormat); + + if (bufferSRVIt != mBufferResourceViews.end()) + { + return bufferSRVIt->second; + } + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11ShaderResourceView *bufferSRV = nullptr; + + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(srvFormat); + + D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; + bufferSRVDesc.Buffer.ElementOffset = 0; + bufferSRVDesc.Buffer.ElementWidth = static_cast<UINT>(mBufferSize) / dxgiFormatInfo.pixelBytes; + bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + bufferSRVDesc.Format = srvFormat; + + HRESULT result = device->CreateShaderResourceView(mNativeStorage, &bufferSRVDesc, &bufferSRV); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Error creating buffer SRV in Buffer11::NativeStorage::getSRVForFormat"); + } + + mBufferResourceViews[srvFormat] = bufferSRV; + + return bufferSRV; +} + +void Buffer11::NativeStorage::clearSRVs() +{ + for (auto &srv : mBufferResourceViews) + { + SafeRelease(srv.second); + } + mBufferResourceViews.clear(); +} + +// Buffer11::EmulatedIndexStorage implementation + Buffer11::EmulatedIndexedStorage::EmulatedIndexedStorage(Renderer11 *renderer) : BufferStorage(renderer, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), mNativeStorage(nullptr) { @@ -1215,7 +1265,7 @@ gl::ErrorOrResult<CopyResult> Buffer11::EmulatedIndexedStorage::copyFromStorage( size_t size, size_t destOffset) { - ASSERT(source->isMappable()); + ASSERT(source->isMappable(GL_MAP_READ_BIT)); uint8_t *sourceData = nullptr; ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); ASSERT(destOffset + size <= mMemoryBuffer.size()); @@ -1253,6 +1303,8 @@ void Buffer11::EmulatedIndexedStorage::unmap() // No-op } +// Buffer11::PackStorage implementation + Buffer11::PackStorage::PackStorage(Renderer11 *renderer) : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK), mStagingTexture(), mDataModified(false) { @@ -1267,9 +1319,16 @@ gl::ErrorOrResult<CopyResult> Buffer11::PackStorage::copyFromStorage(BufferStora size_t size, size_t destOffset) { - // We copy through a staging buffer when drawing with a pack buffer, - // or for other cases where we access the pack buffer - UNREACHABLE(); + ANGLE_TRY(flushQueuedPackCommand()); + + // We copy through a staging buffer when drawing with a pack buffer, or for other cases where we + // access the pack buffer + ASSERT(source->isMappable(GL_MAP_READ_BIT) && source->getUsage() == BUFFER_USAGE_STAGING); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); + ASSERT(destOffset + size <= mMemoryBuffer.size()); + memcpy(mMemoryBuffer.data() + destOffset, sourceData, size); + source->unmap(); return CopyResult::NOT_RECREATED; } @@ -1324,7 +1383,7 @@ gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &rea unsigned int srcSubresource = renderTarget->getSubresourceIndex(); TextureHelper11 srcTexture = - TextureHelper11::MakeAndReference(renderTargetResource, renderTarget->getANGLEFormat()); + TextureHelper11::MakeAndReference(renderTargetResource, renderTarget->getFormatSet()); mQueuedPackCommand.reset(new PackPixelsParams(params)); @@ -1333,7 +1392,7 @@ gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &rea mStagingTexture.getExtents() != srcTextureSize) { ANGLE_TRY_RESULT( - CreateStagingTexture(srcTexture.getTextureType(), srcTexture.getANGLEFormat(), + CreateStagingTexture(srcTexture.getTextureType(), srcTexture.getFormatSet(), srcTextureSize, StagingAccess::READ, mRenderer->getDevice()), mStagingTexture); } @@ -1377,6 +1436,8 @@ gl::Error Buffer11::PackStorage::flushQueuedPackCommand() return gl::NoError(); } +// Buffer11::SystemMemoryStorage implementation + Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer) : Buffer11::BufferStorage(renderer, BUFFER_USAGE_SYSTEM_MEMORY) { @@ -1387,7 +1448,7 @@ gl::ErrorOrResult<CopyResult> Buffer11::SystemMemoryStorage::copyFromStorage(Buf size_t size, size_t destOffset) { - ASSERT(source->isMappable()); + ASSERT(source->isMappable(GL_MAP_READ_BIT)); uint8_t *sourceData = nullptr; ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); ASSERT(destOffset + size <= mSystemCopy.size()); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h index 6d56501d86d..dcf9a03732e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h @@ -9,6 +9,7 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ +#include <array> #include <map> #include "libANGLE/angletypes.h" @@ -68,8 +69,8 @@ class Buffer11 : public BufferD3D void invalidateStaticData() override; // BufferImpl implementation - gl::Error setData(const void *data, size_t size, GLenum usage) override; - gl::Error setSubData(const void *data, size_t size, size_t offset) override; + gl::Error setData(GLenum target, const void *data, size_t size, GLenum usage) override; + gl::Error setSubData(GLenum target, const void *data, size_t size, size_t offset) override; gl::Error copySubData(BufferImpl *source, GLintptr sourceOffset, GLintptr destOffset, @@ -100,7 +101,7 @@ class Buffer11 : public BufferD3D unsigned int lruCount; }; - gl::Error markBufferUsage(); + gl::Error markBufferUsage(BufferUsage usage); gl::ErrorOrResult<NativeStorage *> getStagingStorage(); gl::ErrorOrResult<PackStorage *> getPackStorage(); gl::ErrorOrResult<SystemMemoryStorage *> getSystemMemoryStorage(); @@ -113,14 +114,21 @@ class Buffer11 : public BufferD3D GLsizeiptr size); BufferStorage *allocateStorage(BufferUsage usage); - void updateSystemMemoryDeallocThreshold(); + void updateDeallocThreshold(BufferUsage usage); + + // Free the storage if we decide it isn't being used very often. + gl::Error checkForDeallocation(BufferUsage usage); Renderer11 *mRenderer; size_t mSize; BufferStorage *mMappedStorage; - std::vector<BufferStorage *> mBufferStorages; + std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages; + + // These two arrays are used to track when to free unused storage. + std::array<unsigned int, BUFFER_USAGE_COUNT> mDeallocThresholds; + std::array<unsigned int, BUFFER_USAGE_COUNT> mIdleness; // Cache of D3D11 constant buffer for specific ranges of buffer data. // This is used to emulate UBO ranges on 11.0 devices. @@ -130,12 +138,6 @@ class Buffer11 : public BufferD3D size_t mConstantBufferStorageAdditionalSize; unsigned int mMaxConstantBufferLruCount; - typedef std::pair<ID3D11Buffer *, ID3D11ShaderResourceView *> BufferSRVPair; - std::map<DXGI_FORMAT, BufferSRVPair> mBufferResourceViews; - - unsigned int mReadUsageCount; - unsigned int mSystemMemoryDeallocThreshold; - angle::BroadcastChannel mStaticBroadcastChannel; angle::BroadcastChannel mDirectBroadcastChannel; }; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp index 369797ac5f5..7cf003a4841 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp @@ -281,17 +281,18 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, return error; } - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment.getInternalFormat()); + const gl::InternalFormat &formatInfo = *attachment.getFormat().info; if (clearParams.colorClearType == GL_FLOAT && - !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED)) + !(formatInfo.componentType == GL_FLOAT || + formatInfo.componentType == GL_UNSIGNED_NORMALIZED || + formatInfo.componentType == GL_SIGNED_NORMALIZED)) { - ERR( - "It is undefined behaviour to clear a render buffer which is not normalized " + ERR("It is undefined behaviour to clear a render buffer which is not normalized " "fixed point or floating-" "point to floating point values (color attachment %u has internal format " "0x%X).", - colorAttachmentIndex, attachment.getInternalFormat()); + colorAttachmentIndex, attachment.getFormat().asSized()); } if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && @@ -302,10 +303,12 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, // Every channel either does not exist in the render target or is masked out continue; } - else if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) || clearParams.colorClearType != GL_FLOAT || - (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + else if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && + needScissoredClear) || + clearParams.colorClearType != GL_FLOAT || + (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || - (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { // A masked clear is required, or a scissored clear is required and ID3D11DeviceContext1::ClearView is unavailable @@ -328,20 +331,26 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); } - const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo( - d3d11::GetANGLEFormatSet(renderTarget->getANGLEFormat()).rtvFormat); + const auto &nativeFormat = renderTarget->getFormatSet().format; // Check if the actual format has a channel that the internal format does not and set them to the // default values - float clearValues[4] = - { - ((formatInfo.redBits == 0 && dxgiFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), - ((formatInfo.greenBits == 0 && dxgiFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), - ((formatInfo.blueBits == 0 && dxgiFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), - ((formatInfo.alphaBits == 0 && dxgiFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), + float clearValues[4] = { + ((formatInfo.redBits == 0 && nativeFormat.redBits > 0) + ? 0.0f + : clearParams.colorFClearValue.red), + ((formatInfo.greenBits == 0 && nativeFormat.greenBits > 0) + ? 0.0f + : clearParams.colorFClearValue.green), + ((formatInfo.blueBits == 0 && nativeFormat.blueBits > 0) + ? 0.0f + : clearParams.colorFClearValue.blue), + ((formatInfo.alphaBits == 0 && nativeFormat.alphaBits > 0) + ? 1.0f + : clearParams.colorFClearValue.alpha), }; - if (dxgiFormatInfo.alphaBits == 1) + if (formatInfo.alphaBits == 1) { // Some drivers do not correctly handle calling Clear() on a format with 1-bit alpha. // They can incorrectly round all non-zero values up to 1.0f. Note that WARP does not do this. @@ -382,10 +391,10 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, return error; } - const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo( - d3d11::GetANGLEFormatSet(renderTarget->getANGLEFormat()).dsvFormat); + const auto &nativeFormat = renderTarget->getFormatSet().format; - unsigned int stencilUnmasked = (stencilAttachment != nullptr) ? (1 << dxgiFormatInfo.stencilBits) - 1 : 0; + unsigned int stencilUnmasked = + (stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0; bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; if (needScissoredClear || needMaskedStencilClear) @@ -409,129 +418,139 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, } } - if (maskedClearRenderTargets.size() > 0 || maskedClearDepthStencil) + if (maskedClearRenderTargets.empty() && !maskedClearDepthStencil) { - // To clear the render targets and depth stencil in one pass: - // - // Render a quad clipped to the scissor rectangle which draws the clear color and a blend - // state that will perform the required color masking. - // - // The quad's depth is equal to the depth clear value with a depth stencil state that - // will enable or disable depth test/writes if the depth buffer should be cleared or not. - // - // The rasterizer state's stencil is set to always pass or fail based on if the stencil - // should be cleared or not with a stencil write mask of the stencil clear value. - // - // ====================================================================================== - // - // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- - // buffer that is not normalized fixed point or floating point with floating point values - // are undefined so we can just write floats to them and D3D11 will bit cast them to - // integers. - // - // Also, we don't have to worry about attempting to clear a normalized fixed/floating point - // buffer with integer values because there is no gl API call which would allow it, - // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to - // be a compatible clear type. - - // Bind all the render targets which need clearing - ASSERT(maskedClearRenderTargets.size() <= mRenderer->getNativeCaps().maxDrawBuffers); - std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size()); - for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++) - { - RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget; - ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView(); - if (!rtv) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); - } + return gl::NoError(); + } - rtvs[i] = rtv; - } - ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : nullptr; - - ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets); - const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - const UINT sampleMask = 0xFFFFFFFF; - - ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams); - const UINT stencilClear = clearParams.stencilClearValue & 0xFF; - - // Set the vertices - UINT vertexStride = 0; - const UINT startIdx = 0; - ClearShader *shader = nullptr; - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) + // To clear the render targets and depth stencil in one pass: + // + // Render a quad clipped to the scissor rectangle which draws the clear color and a blend + // state that will perform the required color masking. + // + // The quad's depth is equal to the depth clear value with a depth stencil state that + // will enable or disable depth test/writes if the depth buffer should be cleared or not. + // + // The rasterizer state's stencil is set to always pass or fail based on if the stencil + // should be cleared or not with a stencil write mask of the stencil clear value. + // + // ====================================================================================== + // + // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- + // buffer that is not normalized fixed point or floating point with floating point values + // are undefined so we can just write floats to them and D3D11 will bit cast them to + // integers. + // + // Also, we don't have to worry about attempting to clear a normalized fixed/floating point + // buffer with integer values because there is no gl API call which would allow it, + // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to + // be a compatible clear type. + + // Bind all the render targets which need clearing + ASSERT(maskedClearRenderTargets.size() <= mRenderer->getNativeCaps().maxDrawBuffers); + std::vector<ID3D11RenderTargetView *> rtvs(maskedClearRenderTargets.size()); + for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++) + { + RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget; + ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView(); + if (!rtv) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result); + return gl::Error(GL_OUT_OF_MEMORY, + "Internal render target view pointer unexpectedly null."); } - const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr; - switch (clearParams.colorClearType) - { - case GL_FLOAT: - ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData); + rtvs[i] = rtv; + } + ID3D11DepthStencilView *dsv = + maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : nullptr; + + ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets); + const FLOAT blendFactors[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + const UINT sampleMask = 0xFFFFFFFF; + + ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams); + const UINT stencilClear = clearParams.stencilClearValue & 0xFF; + + // Set the vertices + UINT vertexStride = 0; + const UINT startIdx = 0; + ClearShader *shader = nullptr; + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = + deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", + result); + } + + const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr; + switch (clearParams.colorClearType) + { + case GL_FLOAT: + ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, + clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>); - shader = mFloatClearShader; + shader = mFloatClearShader; break; - case GL_UNSIGNED_INT: - ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData); + case GL_UNSIGNED_INT: + ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, + clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>); - shader = mUintClearShader; + shader = mUintClearShader; break; - case GL_INT: - ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData); + case GL_INT: + ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, + clearParams.depthClearValue, mappedResource.pData); vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>); - shader = mIntClearShader; + shader = mIntClearShader; break; - default: + default: UNREACHABLE(); break; - } - - deviceContext->Unmap(mVertexBuffer, 0); - - // Set the viewport to be the same size as the framebuffer - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = static_cast<FLOAT>(framebufferSize.width); - viewport.Height = static_cast<FLOAT>(framebufferSize.height); - viewport.MinDepth = 0; - viewport.MaxDepth = 1; - deviceContext->RSSetViewports(1, &viewport); - - // Apply state - deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); - deviceContext->OMSetDepthStencilState(dsState, stencilClear); - deviceContext->RSSetState(mRasterizerState); - - // Apply shaders - deviceContext->IASetInputLayout(shader->inputLayout->resolve(device)); - deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0); - deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0); - deviceContext->GSSetShader(nullptr, nullptr, 0); - - // Apply vertex buffer - deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); - deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // Apply render targets - mRenderer->getStateManager()->setOneTimeRenderTargets(rtvs, dsv); - - // Draw the clear quad - deviceContext->Draw(4, 0); - - // Clean up - mRenderer->markAllStateDirty(); } - return gl::Error(GL_NO_ERROR); + deviceContext->Unmap(mVertexBuffer, 0); + + // Set the viewport to be the same size as the framebuffer + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = static_cast<FLOAT>(framebufferSize.width); + viewport.Height = static_cast<FLOAT>(framebufferSize.height); + viewport.MinDepth = 0; + viewport.MaxDepth = 1; + deviceContext->RSSetViewports(1, &viewport); + + // Apply state + deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); + deviceContext->OMSetDepthStencilState(dsState, stencilClear); + deviceContext->RSSetState(mRasterizerState); + + // Apply shaders + deviceContext->IASetInputLayout(shader->inputLayout->resolve(device)); + deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0); + deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0); + deviceContext->GSSetShader(nullptr, nullptr, 0); + + // Apply vertex buffer + deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); + deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // Apply render targets + mRenderer->getStateManager()->setOneTimeRenderTargets(rtvs, dsv); + + // Draw the clear quad + deviceContext->Draw(4, 0); + + // Clean up + mRenderer->markAllStateDirty(); + + return gl::NoError(); } ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts) diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp index 5eb28e73473..4ebac601667 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp @@ -16,12 +16,12 @@ #include "libANGLE/renderer/d3d/RenderbufferD3D.h" #include "libANGLE/renderer/d3d/SamplerD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" #include "libANGLE/renderer/d3d/d3d11/Fence11.h" #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/StateManager11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" namespace rx @@ -55,7 +55,7 @@ CompilerImpl *Context11::createCompiler() ShaderImpl *Context11::createShader(const gl::ShaderState &data) { - return new ShaderD3D(data); + return new ShaderD3D(data, mRenderer->getWorkarounds()); } ProgramImpl *Context11::createProgram(const gl::ProgramState &data) @@ -121,9 +121,9 @@ FenceSyncImpl *Context11::createFenceSync() return new FenceSync11(mRenderer); } -TransformFeedbackImpl *Context11::createTransformFeedback() +TransformFeedbackImpl *Context11::createTransformFeedback(const gl::TransformFeedbackState &state) { - return new TransformFeedbackD3D(); + return new TransformFeedback11(state, mRenderer); } SamplerImpl *Context11::createSampler() @@ -189,24 +189,9 @@ gl::Error Context11::drawRangeElements(GLenum mode, return mRenderer->genericDrawElements(this, mode, count, type, indices, 0, indexRange); } -void Context11::notifyDeviceLost() +GLenum Context11::getResetStatus() { - mRenderer->notifyDeviceLost(); -} - -bool Context11::isDeviceLost() const -{ - return mRenderer->isDeviceLost(); -} - -bool Context11::testDeviceLost() -{ - return mRenderer->testDeviceLost(); -} - -bool Context11::testDeviceResettable() -{ - return mRenderer->testDeviceResettable(); + return mRenderer->getResetStatus(); } std::string Context11::getVendorString() const diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h index 2f422601025..debf2f9be44 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h @@ -50,7 +50,8 @@ class Context11 : public ContextImpl FenceSyncImpl *createFenceSync() override; // Transform Feedback creation - TransformFeedbackImpl *createTransformFeedback() override; + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; // Sampler object creation SamplerImpl *createSampler() override; @@ -88,11 +89,8 @@ class Context11 : public ContextImpl const GLvoid *indices, const gl::IndexRange &indexRange) override; - // TODO(jmadill): Investigate proper impl methods for this. - void notifyDeviceLost() override; - bool isDeviceLost() const override; - bool testDeviceLost() override; - bool testDeviceResettable() override; + // Device loss + GLenum getResetStatus() override; // Vendor and description strings. std::string getVendorString() const override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp index f9d28e84082..93343f281f3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp @@ -68,7 +68,7 @@ void DebugAnnotator11::setMarker(const wchar_t *markerName) bool DebugAnnotator11::getStatus() { #if defined(ANGLE_ENABLE_WINDOWS_STORE) -#if (NTDDI_VERSION == NTDDI_WIN10) + static_assert(NTDDI_VERSION >= NTDDI_WIN10, "GetStatus only works on Win10 and above"); initializeDevice(); if (mUserDefinedAnnotation != nullptr) @@ -77,38 +77,6 @@ bool DebugAnnotator11::getStatus() } return true; // Default if initializeDevice() failed -#elif defined(_DEBUG) - static bool underCapture = true; - - // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in - // Windows 8.1/Visual Studio 2013. We can use IDXGraphicsAnalysis, though. - // The call to GetDebugInterface1 only succeeds if the app is under capture. - // This should only be called in DEBUG mode. - // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows - // Store ingestion checks. - - // Cache the result to reduce the number of calls to DXGIGetDebugInterface1 - static bool triedIDXGraphicsAnalysis = false; - - if (!triedIDXGraphicsAnalysis) - { - IDXGraphicsAnalysis *graphicsAnalysis = nullptr; - - HRESULT result = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis)); - if (SUCCEEDED(result)) - { - underCapture = (graphicsAnalysis != nullptr); - } - - SafeRelease(graphicsAnalysis); - triedIDXGraphicsAnalysis = true; - } - - return underCapture; -#else - // We can't detect GetStatus() on release WinRT 8.1 builds, so always return true. - return true; -#endif // (NTDDI_VERSION == NTDDI_WIN10) or _DEBUG #else // We can't detect GetStatus() on desktop ANGLE builds so always return true. return true; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp index 53fac65f2a8..fb3a183361c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp @@ -14,6 +14,8 @@ namespace rx { +static const int kDeviceLostCheckPeriod = 64; + // // Template helpers for set and test operations. // @@ -50,10 +52,6 @@ gl::Error FenceTestHelper(FenceClass *fence, bool flushCommandBuffer, GLboolean { return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result); } - else if (fence->mRenderer->isDeviceLost()) - { - return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query."); - } ASSERT(result == S_OK || result == S_FALSE); *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); @@ -89,14 +87,23 @@ gl::Error FenceNV11::test(GLboolean *outFinished) gl::Error FenceNV11::finish() { GLboolean finished = GL_FALSE; + + int loopCount = 0; while (finished != GL_TRUE) { + loopCount++; gl::Error error = FenceTestHelper(this, true, &finished); if (error.isError()) { return error; } + if (loopCount % kDeviceLostCheckPeriod == 0 && mRenderer->testDeviceLost()) + { + return gl::Error(GL_OUT_OF_MEMORY, + "Device was lost while querying result of an event query."); + } + ScheduleYield(); } @@ -176,8 +183,10 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout) * static_cast<LONGLONG>(1000000ll); LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; + int loopCount = 0; while (currentCounter.QuadPart < endCounter && !result) { + loopCount++; ScheduleYield(); success = QueryPerformanceCounter(¤tCounter); UNUSED_ASSERTION_VARIABLE(success); @@ -189,6 +198,13 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou *outResult = GL_WAIT_FAILED; return error; } + + if ((loopCount % kDeviceLostCheckPeriod) == 0 && mRenderer->testDeviceLost()) + { + *outResult = GL_WAIT_FAILED; + return gl::Error(GL_OUT_OF_MEMORY, + "Device was lost while querying result of an event query."); + } } if (currentCounter.QuadPart >= endCounter) diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp index dee9488f75b..a70287ccb4a 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp @@ -29,7 +29,7 @@ namespace rx namespace { -gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *attachment) +gl::Error MarkAttachmentsDirty(const gl::FramebufferAttachment *attachment) { if (attachment && attachment->type() == GL_TEXTURE) { @@ -45,7 +45,7 @@ gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *attachme TextureStorage11 *texStorage11 = GetAs<TextureStorage11>(texStorage); ASSERT(texStorage11); - texStorage11->invalidateSwizzleCacheLevel(attachment->mipLevel()); + texStorage11->markLevelDirty(attachment->mipLevel()); } } @@ -89,18 +89,18 @@ Framebuffer11::~Framebuffer11() { } -gl::Error Framebuffer11::invalidateSwizzles() const +gl::Error Framebuffer11::markAttachmentsDirty() const { for (const auto &colorAttachment : mState.getColorAttachments()) { if (colorAttachment.isAttached()) { - ANGLE_TRY(InvalidateAttachmentSwizzles(&colorAttachment)); + ANGLE_TRY(MarkAttachmentsDirty(&colorAttachment)); } } - ANGLE_TRY(InvalidateAttachmentSwizzles(mState.getDepthAttachment())); - ANGLE_TRY(InvalidateAttachmentSwizzles(mState.getStencilAttachment())); + ANGLE_TRY(MarkAttachmentsDirty(mState.getDepthAttachment())); + ANGLE_TRY(MarkAttachmentsDirty(mState.getStencilAttachment())); return gl::NoError(); } @@ -128,7 +128,7 @@ gl::Error Framebuffer11::clearImpl(ContextImpl *context, const ClearParameters & ANGLE_TRY(clearer->clearFramebuffer(clearParams, mState)); } - ANGLE_TRY(invalidateSwizzles()); + ANGLE_TRY(markAttachmentsDirty()); return gl::NoError(); } @@ -262,13 +262,6 @@ gl::Error Framebuffer11::readPixelsImpl(const gl::Rectangle &area, gl::Buffer *packBuffer = pack.pixelBuffer.get(); if (packBuffer != nullptr) { - if (pack.rowLength != 0 || pack.skipRows != 0 || pack.skipPixels != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, - "Unimplemented pixel store parameters in readPixelsImpl"); - } - Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer); PackPixelsParams packParams(area, format, type, static_cast<GLuint>(outputPitch), pack, reinterpret_cast<ptrdiff_t>(pixels)); @@ -358,14 +351,14 @@ gl::Error Framebuffer11::blitImpl(const gl::Rectangle &sourceArea, blitDepth, blitStencil)); } - ANGLE_TRY(invalidateSwizzles()); + ANGLE_TRY(markAttachmentsDirty()); return gl::NoError(); } GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const { RenderTarget11 *renderTarget11 = GetAs<RenderTarget11>(renderTarget); - return d3d11::GetANGLEFormatSet(renderTarget11->getANGLEFormat()).glInternalFormat; + return renderTarget11->getFormatSet().format.fboImplementationInternalFormat; } void Framebuffer11::updateColorRenderTarget(size_t colorIndex) diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h index 813e0f32f51..b1683a20607 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h @@ -28,7 +28,7 @@ class Framebuffer11 : public FramebufferD3D, public angle::SignalReceiver gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; // Invalidate the cached swizzles of all bound texture attachments. - gl::Error invalidateSwizzles() const; + gl::Error markAttachmentsDirty() const; void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp index bc698f33ea7..c1d4d413c19 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp @@ -67,8 +67,8 @@ gl::Error Image11::generateMipmap(Image11 *dest, const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(srcMapped.pData); uint8_t *destData = reinterpret_cast<uint8_t*>(destMapped.pData); - auto mipGenerationFunction = d3d11::GetTextureFormatInfo(src->getInternalFormat(), rendererCaps) - .formatSet->mipGenerationFunction; + auto mipGenerationFunction = + d3d11::Format::Get(src->getInternalFormat(), rendererCaps).format.mipGenerationFunction; mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, destData, destMapped.RowPitch, destMapped.DepthPitch); @@ -90,7 +90,7 @@ bool Image11::isDirty() const if (mDirty && !mStagingTexture && !mRecoverFromStorage) { const Renderer11DeviceCaps &deviceCaps = mRenderer->getRenderer11DeviceCaps(); - const auto &formatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, deviceCaps); + const auto &formatInfo = d3d11::Format::Get(mInternalFormat, deviceCaps); if (formatInfo.dataInitializerFunction == nullptr) { return false; @@ -220,10 +220,10 @@ bool Image11::redefine(GLenum target, GLenum internalformat, const gl::Extents & mTarget = target; // compute the d3d format that will be used - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalformat, mRenderer->getRenderer11DeviceCaps()); - mDXGIFormat = formatInfo.formatSet->texFormat; - mRenderable = (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN); + const d3d11::Format &formatInfo = + d3d11::Format::Get(internalformat, mRenderer->getRenderer11DeviceCaps()); + mDXGIFormat = formatInfo.texFormat; + mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); releaseStagingTexture(); mDirty = (formatInfo.dataInitializerFunction != NULL); @@ -257,20 +257,19 @@ gl::Error Image11::loadData(const gl::Box &area, formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength), inputRowPitch); GLuint inputDepthPitch = 0; - ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, - unpack.rowLength, unpack.imageHeight), + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, unpack.imageHeight, inputRowPitch), inputDepthPitch); GLuint inputSkipBytes = 0; ANGLE_TRY_RESULT( - formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack.skipImages, - unpack.skipRows, unpack.skipPixels, applySkipImages), + formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages), inputSkipBytes); const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type).loadFunction; + const d3d11::Format &d3dFormatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions(type).loadFunction; D3D11_MAPPED_SUBRESOURCE mappedImage; gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); @@ -295,9 +294,7 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input) GLsizei inputRowPitch = 0; ANGLE_TRY_RESULT(formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0), inputRowPitch); GLsizei inputDepthPitch = 0; - ANGLE_TRY_RESULT( - formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0), - inputDepthPitch); + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, 0, inputRowPitch), inputDepthPitch); const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; @@ -307,8 +304,9 @@ gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input) ASSERT(area.x % outputBlockWidth == 0); ASSERT(area.y % outputBlockHeight == 0); - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE).loadFunction; + const d3d11::Format &d3dFormatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions(GL_UNSIGNED_BYTE).loadFunction; D3D11_MAPPED_SUBRESOURCE mappedImage; gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); @@ -343,7 +341,7 @@ gl::Error Image11::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureS UINT subresourceIndex = storage11->getSubresourceIndex(imageIndex); TextureHelper11 textureHelper = - TextureHelper11::MakeAndReference(resource, storage11->getANGLEFormat()); + TextureHelper11::MakeAndReference(resource, storage11->getFormatSet()); gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth); return copyWithoutConversion(gl::Offset(), sourceBox, textureHelper, subresourceIndex); @@ -356,11 +354,11 @@ gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset, const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorbuffer(); ASSERT(srcAttachment); - GLenum sourceInternalFormat = srcAttachment->getInternalFormat(); + GLenum sourceInternalFormat = srcAttachment->getFormat().asSized(); const auto &d3d11Format = - d3d11::GetTextureFormatInfo(sourceInternalFormat, mRenderer->getRenderer11DeviceCaps()); + d3d11::Format::Get(sourceInternalFormat, mRenderer->getRenderer11DeviceCaps()); - if (d3d11Format.formatSet->texFormat == mDXGIFormat && sourceInternalFormat == mInternalFormat) + if (d3d11Format.texFormat == mDXGIFormat && sourceInternalFormat == mInternalFormat) { RenderTargetD3D *renderTarget = nullptr; gl::Error error = srcAttachment->getRenderTarget(&renderTarget); @@ -373,7 +371,7 @@ gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset, ASSERT(rt11->getTexture()); TextureHelper11 textureHelper = - TextureHelper11::MakeAndReference(rt11->getTexture(), rt11->getANGLEFormat()); + TextureHelper11::MakeAndReference(rt11->getTexture(), rt11->getFormatSet()); unsigned int sourceSubResource = rt11->getSubresourceIndex(); gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1); @@ -399,9 +397,9 @@ gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset, const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(mInternalFormat); const auto &destD3D11Format = - d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - auto loadFunction = destD3D11Format.loadFunctions.at(destFormatInfo.type); + auto loadFunction = destD3D11Format.loadFunctions(destFormatInfo.type); if (loadFunction.requiresConversion) { size_t bufferSize = destFormatInfo.pixelBytes * sourceArea.width * sourceArea.height; @@ -564,7 +562,8 @@ gl::Error Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL) + if (d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()) + .dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector<std::vector<BYTE>> textureData; @@ -604,7 +603,8 @@ gl::Error Image11::createStagingTexture() desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; desc.MiscFlags = 0; - if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL) + if (d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()) + .dataInitializerFunction != NULL) { std::vector<D3D11_SUBRESOURCE_DATA> initialData; std::vector<std::vector<BYTE>> textureData; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp index f73b8aa6122..e7ca56ef2b0 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -196,8 +196,9 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format; GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType); - const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat, mRenderer->getRenderer11DeviceCaps()); - DXGI_FORMAT srvFormat = sourceFormatInfo.formatSet->srvFormat; + const d3d11::Format &sourceFormatInfo = + d3d11::Format::Get(sourceFormat, mRenderer->getRenderer11DeviceCaps()); + DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); Buffer11 *bufferStorage11 = GetAs<Buffer11>(sourceBuffer.getImplementation()); ID3D11ShaderResourceView *bufferSRV = nullptr; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp index 171cebf202b..6449c9e6a58 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp @@ -18,7 +18,9 @@ namespace rx { -static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) +namespace +{ +bool GetTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) { ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource); if (texture1D) @@ -62,7 +64,7 @@ static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLeve return false; } -static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) +unsigned int GetRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; view->GetDesc(&rtvDesc); @@ -72,58 +74,58 @@ static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11Rende switch (rtvDesc.ViewDimension) { - case D3D11_RTV_DIMENSION_TEXTURE1D: - mipSlice = rtvDesc.Texture1D.MipSlice; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: - mipSlice = rtvDesc.Texture1DArray.MipSlice; - arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2D: - mipSlice = rtvDesc.Texture2D.MipSlice; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: - mipSlice = rtvDesc.Texture2DArray.MipSlice; - arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DMS: - mipSlice = 0; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: - mipSlice = 0; - arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; - break; - - case D3D11_RTV_DIMENSION_TEXTURE3D: - mipSlice = rtvDesc.Texture3D.MipSlice; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_UNKNOWN: - case D3D11_RTV_DIMENSION_BUFFER: - UNIMPLEMENTED(); - break; - - default: - UNREACHABLE(); - break; + case D3D11_RTV_DIMENSION_TEXTURE1D: + mipSlice = rtvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + mipSlice = rtvDesc.Texture1DArray.MipSlice; + arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2D: + mipSlice = rtvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + mipSlice = rtvDesc.Texture2DArray.MipSlice; + arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE3D: + mipSlice = rtvDesc.Texture3D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_RTV_DIMENSION_BUFFER: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; } unsigned int mipLevels, samples; - getTextureProperties(resource, &mipLevels, &samples); + GetTextureProperties(resource, &mipLevels, &samples); return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) +unsigned int GetDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; view->GetDesc(&dsvDesc); @@ -133,52 +135,66 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth switch (dsvDesc.ViewDimension) { - case D3D11_DSV_DIMENSION_TEXTURE1D: - mipSlice = dsvDesc.Texture1D.MipSlice; - arraySlice = 0; - break; - - case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: - mipSlice = dsvDesc.Texture1DArray.MipSlice; - arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2D: - mipSlice = dsvDesc.Texture2D.MipSlice; - arraySlice = 0; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: - mipSlice = dsvDesc.Texture2DArray.MipSlice; - arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DMS: - mipSlice = 0; - arraySlice = 0; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: - mipSlice = 0; - arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; - break; - - case D3D11_DSV_DIMENSION_UNKNOWN: - UNIMPLEMENTED(); - break; - - default: - UNREACHABLE(); - break; + case D3D11_DSV_DIMENSION_TEXTURE1D: + mipSlice = dsvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + mipSlice = dsvDesc.Texture1DArray.MipSlice; + arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2D: + mipSlice = dsvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + mipSlice = dsvDesc.Texture2DArray.MipSlice; + arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_UNKNOWN: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; } unsigned int mipLevels, samples; - getTextureProperties(resource, &mipLevels, &samples); + GetTextureProperties(resource, &mipLevels, &samples); return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -RenderTarget11::RenderTarget11(d3d11::ANGLEFormat angleFormat) : mANGLEFormat(angleFormat) +GLenum GetSurfaceRTFormat(bool depth, SwapChain11 *swapChain) +{ + return (depth ? swapChain->getDepthBufferInternalFormat() + : swapChain->getRenderTargetInternalFormat()); +} + +const d3d11::Format &GetSurfaceFormatSet(bool depth, SwapChain11 *swapChain, Renderer11 *renderer) +{ + return d3d11::Format::Get(GetSurfaceRTFormat(depth, swapChain), + renderer->getRenderer11DeviceCaps()); +} + +} // anonymous namespace + +RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(formatSet) { } @@ -200,12 +216,12 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11ShaderResourceView *srv, ID3D11ShaderResourceView *blitSRV, GLenum internalFormat, - d3d11::ANGLEFormat angleFormat, + const d3d11::Format &formatSet, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) - : RenderTarget11(angleFormat), + : RenderTarget11(formatSet), mWidth(width), mHeight(height), mDepth(depth), @@ -240,21 +256,21 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, if (mRenderTarget && mTexture) { - mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); + mSubresourceIndex = GetRTVSubresourceIndex(mTexture, mRenderTarget); } - ASSERT(mANGLEFormat != d3d11::ANGLE_FORMAT_NONE || mWidth == 0 || mHeight == 0); + ASSERT(mFormatSet.format.id != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0); } TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLenum internalFormat, - d3d11::ANGLEFormat angleFormat, + const d3d11::Format &formatSet, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) - : RenderTarget11(angleFormat), + : RenderTarget11(formatSet), mWidth(width), mHeight(height), mDepth(depth), @@ -284,9 +300,9 @@ TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, if (mDepthStencil && mTexture) { - mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); + mSubresourceIndex = GetDSVSubresourceIndex(mTexture, mDepthStencil); } - ASSERT(mANGLEFormat != d3d11::ANGLE_FORMAT_NONE || mWidth == 0 || mHeight == 0); + ASSERT(mFormatSet.format.id != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0); } TextureRenderTarget11::~TextureRenderTarget11() @@ -356,16 +372,11 @@ unsigned int TextureRenderTarget11::getSubresourceIndex() const SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth) - : RenderTarget11(d3d11::ANGLE_FORMAT_NONE), // format will be determined in constructor body + : RenderTarget11(GetSurfaceFormatSet(depth, swapChain, renderer)), mSwapChain(swapChain), - mRenderer(renderer), mDepth(depth) { ASSERT(mSwapChain); - - mANGLEFormat = d3d11::GetTextureFormatInfo(getInternalFormatInternal(), - mRenderer->getRenderer11DeviceCaps()) - .formatSet->format; } SurfaceRenderTarget11::~SurfaceRenderTarget11() @@ -389,12 +400,7 @@ GLsizei SurfaceRenderTarget11::getDepth() const GLenum SurfaceRenderTarget11::getInternalFormat() const { - return getInternalFormatInternal(); -} - -GLenum SurfaceRenderTarget11::getInternalFormatInternal() const -{ - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); + return GetSurfaceRTFormat(mDepth, mSwapChain); } GLsizei SurfaceRenderTarget11::getSamples() const @@ -435,4 +441,4 @@ unsigned int SurfaceRenderTarget11::getSubresourceIndex() const return 0; } -} +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h index 19c824b0485..4ee0de29203 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h @@ -23,7 +23,7 @@ class Renderer11; class RenderTarget11 : public RenderTargetD3D { public: - RenderTarget11(d3d11::ANGLEFormat angleFormat); + RenderTarget11(const d3d11::Format &formatSet); virtual ~RenderTarget11(); virtual ID3D11Resource *getTexture() const = 0; @@ -37,11 +37,11 @@ class RenderTarget11 : public RenderTargetD3D void signalDirty() override; angle::BroadcastChannel *getBroadcastChannel() { return &mBroadcastChannel; } - d3d11::ANGLEFormat getANGLEFormat() const { return mANGLEFormat; } + const d3d11::Format &getFormatSet() const { return mFormatSet; } protected: angle::BroadcastChannel mBroadcastChannel; - d3d11::ANGLEFormat mANGLEFormat; + const d3d11::Format &mFormatSet; }; class TextureRenderTarget11 : public RenderTarget11 @@ -53,7 +53,7 @@ class TextureRenderTarget11 : public RenderTarget11 ID3D11ShaderResourceView *srv, ID3D11ShaderResourceView *blitSRV, GLenum internalFormat, - d3d11::ANGLEFormat angleFormat, + const d3d11::Format &formatSet, GLsizei width, GLsizei height, GLsizei depth, @@ -62,7 +62,7 @@ class TextureRenderTarget11 : public RenderTarget11 ID3D11Resource *resource, ID3D11ShaderResourceView *srv, GLenum internalFormat, - d3d11::ANGLEFormat angleFormat, + const d3d11::Format &formatSet, GLsizei width, GLsizei height, GLsizei depth, @@ -122,12 +122,7 @@ class SurfaceRenderTarget11 : public RenderTarget11 unsigned int getSubresourceIndex() const override; private: - // The internal versions of the functions are needed so that they can be safely called - // from the constructor. - GLenum getInternalFormatInternal() const; - SwapChain11 *mSwapChain; - Renderer11 *mRenderer; bool mDepth; }; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp index 360b66bfffb..5e92a25b8c3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp @@ -9,6 +9,7 @@ #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include <EGL/eglext.h> +#include <iomanip> #include <sstream> #include <versionhelpers.h> @@ -23,6 +24,7 @@ #include "libANGLE/Program.h" #include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" #include "libANGLE/renderer/d3d/d3d11/Blit11.h" #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" #include "libANGLE/renderer/d3d/d3d11/Clear11.h" @@ -42,6 +44,7 @@ #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" #include "libANGLE/renderer/d3d/d3d11/Trim11.h" #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" #include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" @@ -54,7 +57,6 @@ #include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" #include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/State.h" #include "libANGLE/Surface.h" @@ -444,7 +446,7 @@ Renderer11::Renderer11(egl::Display *display) mAppliedGeometryShader = NULL; mAppliedPixelShader = NULL; - mAppliedNumXFBBindings = static_cast<size_t>(-1); + mAppliedTFObject = angle::DirtyPointer; ZeroMemory(&mAdapterDescription, sizeof(mAdapterDescription)); @@ -883,6 +885,18 @@ void Renderer11::populateRenderer11DeviceCaps() { HRESULT hr = S_OK; + LARGE_INTEGER version; + hr = mDxgiAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &version); + if (FAILED(hr)) + { + mRenderer11DeviceCaps.driverVersion.reset(); + ERR("Error querying driver version from DXGI Adapter."); + } + else + { + mRenderer11DeviceCaps.driverVersion = version; + } + if (mDeviceContext1) { D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options; @@ -894,11 +908,19 @@ void Renderer11::populateRenderer11DeviceCaps() } } - hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G6R5_UNORM, &(mRenderer11DeviceCaps.B5G6R5support)); - if (FAILED(hr)) + if (getWorkarounds().disableB5G6R5Support) { mRenderer11DeviceCaps.B5G6R5support = 0; } + else + { + hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G6R5_UNORM, + &(mRenderer11DeviceCaps.B5G6R5support)); + if (FAILED(hr)) + { + mRenderer11DeviceCaps.B5G6R5support = 0; + } + } hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B4G4R4A4_UNORM, &(mRenderer11DeviceCaps.B4G4R4A4support)); if (FAILED(hr)) @@ -974,6 +996,7 @@ egl::ConfigSet Renderer11::generateConfigs() gl::GetInternalFormatInfo(colorBufferInternalFormat); const gl::InternalFormat &depthStencilBufferFormatInfo = gl::GetInternalFormatInfo(depthStencilBufferInternalFormat); + const gl::Version &maxVersion = getMaxSupportedESVersion(); egl::Config config; config.renderTargetFormat = colorBufferInternalFormat; @@ -991,15 +1014,22 @@ egl::ConfigSet Renderer11::generateConfigs() config.colorBufferType = EGL_RGB_BUFFER; config.configCaveat = EGL_NONE; config.configID = static_cast<EGLint>(configs.size() + 1); - // Can only support a conformant ES2 with feature level greater than 10.0. - config.conformant = (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) - ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) - : 0; // PresentPathFast may not be conformant - if (mPresentPathFastEnabled) + config.conformant = 0; + if (!mPresentPathFastEnabled) { - config.conformant = 0; + // Can only support a conformant ES2 with feature level greater than 10.0. + if (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) + { + config.conformant |= EGL_OPENGL_ES2_BIT; + } + + // We can only support conformant ES3 on FL 10.1+ + if (maxVersion.major >= 3) + { + config.conformant |= EGL_OPENGL_ES3_BIT_KHR; + } } config.depthSize = depthStencilBufferFormatInfo.depthBits; @@ -1013,11 +1043,14 @@ egl::ConfigSet Renderer11::generateConfigs() config.nativeRenderable = EGL_FALSE; config.nativeVisualID = 0; config.nativeVisualType = EGL_NONE; - // Can't support ES3 at all without feature level 10.0 - config.renderableType = - EGL_OPENGL_ES2_BIT | ((mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) - ? EGL_OPENGL_ES3_BIT_KHR - : 0); + + // Can't support ES3 at all without feature level 10.1 + config.renderableType = EGL_OPENGL_ES2_BIT; + if (maxVersion.major >= 3) + { + config.renderableType |= EGL_OPENGL_ES3_BIT_KHR; + } + config.sampleBuffers = 0; // FIXME: enumerate multi-sampling config.samples = 0; config.stencilSize = depthStencilBufferFormatInfo.stencilBits; @@ -1102,11 +1135,15 @@ gl::Error Renderer11::finish() } mDeviceContext->End(mSyncQuery); - mDeviceContext->Flush(); + unsigned int attempt = 0; do { - result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); + unsigned int flushFrequency = 100; + UINT flags = (attempt % flushFrequency == 0) ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH; + attempt++; + + result = mDeviceContext->GetData(mSyncQuery, NULL, 0, flags); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); @@ -1359,61 +1396,48 @@ gl::Error Renderer11::setUniformBuffers(const gl::ContextState &data, GLintptr uniformBufferOffset = uniformBuffer.getOffset(); GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); - if (uniformBuffer.get() != nullptr) + if (uniformBuffer.get() == nullptr) + { + continue; + } + + Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get()); + ID3D11Buffer *constantBuffer = nullptr; + + ANGLE_TRY_RESULT( + bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize), + constantBuffer); + + if (!constantBuffer) { - Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get()); - ID3D11Buffer *constantBuffer; + return gl::Error(GL_OUT_OF_MEMORY, "Error retrieving constant buffer"); + } - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) + if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial() || + mCurrentConstantBufferVSOffset[uniformBufferIndex] != uniformBufferOffset || + mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize) + { + if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) { - auto bufferOrError = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); - if (bufferOrError.isError()) - { - return bufferOrError.getError(); - } - constantBuffer = bufferOrError.getResult(); + UINT firstConstant = 0, numConstants = 0; + CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, + &firstConstant, &numConstants); + mDeviceContext1->VSSetConstantBuffers1( + getReservedVertexUniformBuffers() + + static_cast<unsigned int>(uniformBufferIndex), + 1, &constantBuffer, &firstConstant, &numConstants); } else { - auto bufferOrError = - bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); - if (bufferOrError.isError()) - { - return bufferOrError.getError(); - } - constantBuffer = bufferOrError.getResult(); - } - - if (!constantBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY); + mDeviceContext->VSSetConstantBuffers( + getReservedVertexUniformBuffers() + + static_cast<unsigned int>(uniformBufferIndex), + 1, &constantBuffer); } - if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial() || - mCurrentConstantBufferVSOffset[uniformBufferIndex] != uniformBufferOffset || - mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize) - { - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) - { - UINT firstConstant = 0, numConstants = 0; - CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants); - mDeviceContext1->VSSetConstantBuffers1( - getReservedVertexUniformBuffers() + - static_cast<unsigned int>(uniformBufferIndex), - 1, &constantBuffer, &firstConstant, &numConstants); - } - else - { - mDeviceContext->VSSetConstantBuffers( - getReservedVertexUniformBuffers() + - static_cast<unsigned int>(uniformBufferIndex), - 1, &constantBuffer); - } - - mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial(); - mCurrentConstantBufferVSOffset[uniformBufferIndex] = uniformBufferOffset; - mCurrentConstantBufferVSSize[uniformBufferIndex] = uniformBufferSize; - } + mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial(); + mCurrentConstantBufferVSOffset[uniformBufferIndex] = uniformBufferOffset; + mCurrentConstantBufferVSSize[uniformBufferIndex] = uniformBufferSize; } } @@ -1431,65 +1455,52 @@ gl::Error Renderer11::setUniformBuffers(const gl::ContextState &data, GLintptr uniformBufferOffset = uniformBuffer.getOffset(); GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); - if (uniformBuffer.get() != nullptr) + if (uniformBuffer.get() == nullptr) + { + continue; + } + + Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get()); + ID3D11Buffer *constantBuffer = nullptr; + + ANGLE_TRY_RESULT( + bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize), + constantBuffer); + + if (!constantBuffer) { - Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get()); - ID3D11Buffer *constantBuffer; + return gl::Error(GL_OUT_OF_MEMORY, "Error retrieving constant buffer"); + } - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) + if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial() || + mCurrentConstantBufferPSOffset[uniformBufferIndex] != uniformBufferOffset || + mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize) + { + if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) { - auto bufferOrError = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); - if (bufferOrError.isError()) - { - return bufferOrError.getError(); - } - constantBuffer = bufferOrError.getResult(); + UINT firstConstant = 0, numConstants = 0; + CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, + &firstConstant, &numConstants); + mDeviceContext1->PSSetConstantBuffers1( + getReservedFragmentUniformBuffers() + + static_cast<unsigned int>(uniformBufferIndex), + 1, &constantBuffer, &firstConstant, &numConstants); } else { - auto bufferOrError = - bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); - if (bufferOrError.isError()) - { - return bufferOrError.getError(); - } - constantBuffer = bufferOrError.getResult(); - } - - if (!constantBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY); + mDeviceContext->PSSetConstantBuffers( + getReservedFragmentUniformBuffers() + + static_cast<unsigned int>(uniformBufferIndex), + 1, &constantBuffer); } - if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial() || - mCurrentConstantBufferPSOffset[uniformBufferIndex] != uniformBufferOffset || - mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize) - { - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) - { - UINT firstConstant = 0, numConstants = 0; - CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants); - mDeviceContext1->PSSetConstantBuffers1( - getReservedFragmentUniformBuffers() + - static_cast<unsigned int>(uniformBufferIndex), - 1, &constantBuffer, &firstConstant, &numConstants); - } - else - { - mDeviceContext->PSSetConstantBuffers( - getReservedFragmentUniformBuffers() + - static_cast<unsigned int>(uniformBufferIndex), - 1, &constantBuffer); - } - - mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial(); - mCurrentConstantBufferPSOffset[uniformBufferIndex] = uniformBufferOffset; - mCurrentConstantBufferPSSize[uniformBufferIndex] = uniformBufferSize; - } + mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial(); + mCurrentConstantBufferPSOffset[uniformBufferIndex] = uniformBufferOffset; + mCurrentConstantBufferPSSize[uniformBufferIndex] = uniformBufferSize; } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer11::updateState(const gl::ContextState &data, GLenum drawMode) @@ -1668,76 +1679,40 @@ gl::Error Renderer11::applyIndexBuffer(const gl::ContextState &data, return gl::NoError(); } -gl::Error Renderer11::applyTransformFeedbackBuffers(const gl::State &state) +gl::Error Renderer11::applyTransformFeedbackBuffers(const gl::ContextState &data) { - size_t numXFBBindings = 0; - bool requiresUpdate = false; + const auto &state = data.getState(); - if (state.isTransformFeedbackActiveUnpaused()) + // If transform feedback is not active, unbind all buffers + if (!state.isTransformFeedbackActiveUnpaused()) { - const gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); - numXFBBindings = transformFeedback->getIndexedBufferCount(); - ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); - - for (size_t i = 0; i < numXFBBindings; i++) + if (mAppliedTFObject != 0) { - const OffsetBindingPointer<gl::Buffer> &binding = transformFeedback->getIndexedBuffer(i); - - ID3D11Buffer *d3dBuffer = nullptr; - if (binding.get() != nullptr) - { - Buffer11 *storage = GetImplAs<Buffer11>(binding.get()); - auto bufferOrError = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); - if (bufferOrError.isError()) - { - return bufferOrError.getError(); - } - d3dBuffer = bufferOrError.getResult(); - } - - // TODO: mAppliedTFBuffers and friends should also be kept in a vector. - if (d3dBuffer != mAppliedTFBuffers[i] || binding.getOffset() != mAppliedTFOffsets[i]) - { - requiresUpdate = true; - } + mDeviceContext->SOSetTargets(0, nullptr, nullptr); + mAppliedTFObject = 0; } + return gl::NoError(); } - if (requiresUpdate || numXFBBindings != mAppliedNumXFBBindings) + gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); + TransformFeedback11 *transformFeedback11 = GetImplAs<TransformFeedback11>(transformFeedback); + uintptr_t transformFeedbackId = reinterpret_cast<uintptr_t>(transformFeedback11); + if (mAppliedTFObject == transformFeedbackId && !transformFeedback11->isDirty()) { - const gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); - for (size_t i = 0; i < numXFBBindings; ++i) - { - const OffsetBindingPointer<gl::Buffer> &binding = transformFeedback->getIndexedBuffer(i); - if (binding.get() != nullptr) - { - Buffer11 *storage = GetImplAs<Buffer11>(binding.get()); - auto bufferOrError = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); - if (bufferOrError.isError()) - { - return bufferOrError.getError(); - } - ID3D11Buffer *d3dBuffer = bufferOrError.getResult(); + return gl::NoError(); + } - mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != binding.getOffset()) ? - static_cast<UINT>(binding.getOffset()) : -1; - mAppliedTFBuffers[i] = d3dBuffer; - } - else - { - mAppliedTFBuffers[i] = nullptr; - mCurrentD3DOffsets[i] = 0; - } - mAppliedTFOffsets[i] = binding.getOffset(); - } + const std::vector<ID3D11Buffer *> *soBuffers = nullptr; + ANGLE_TRY_RESULT(transformFeedback11->getSOBuffers(), soBuffers); + const std::vector<UINT> &soOffsets = transformFeedback11->getSOBufferOffsets(); - mAppliedNumXFBBindings = numXFBBindings; + mDeviceContext->SOSetTargets(transformFeedback11->getNumSOBuffers(), soBuffers->data(), + soOffsets.data()); - mDeviceContext->SOSetTargets(static_cast<unsigned int>(numXFBBindings), mAppliedTFBuffers, - mCurrentD3DOffsets); - } + mAppliedTFObject = transformFeedbackId; + transformFeedback11->onApply(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer11::drawArraysImpl(const gl::ContextState &data, @@ -2397,7 +2372,7 @@ void Renderer11::SamplerMetadataD3D11::initData(unsigned int samplerCount) void Renderer11::SamplerMetadataD3D11::update(unsigned int samplerIndex, const gl::Texture &texture) { unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel(); - GLenum internalFormat = texture.getInternalFormat(texture.getTarget(), baseLevel); + GLenum sizedFormat = texture.getFormat(texture.getTarget(), baseLevel).asSized(); if (mSamplerMetadata[samplerIndex].baseLevel != static_cast<int>(baseLevel)) { mSamplerMetadata[samplerIndex].baseLevel = static_cast<int>(baseLevel); @@ -2410,7 +2385,7 @@ void Renderer11::SamplerMetadataD3D11::update(unsigned int samplerIndex, const g bool needIntegerTextureMetadata = false; // internalFormatBits == 0 means a 32-bit texture in the case of integer textures. int internalFormatBits = 0; - switch (internalFormat) + switch (sizedFormat) { case GL_RGBA32I: case GL_RGBA32UI: @@ -2549,13 +2524,7 @@ void Renderer11::markAllStateDirty() mAppliedGeometryShader = angle::DirtyPointer; mAppliedPixelShader = angle::DirtyPointer; - mAppliedNumXFBBindings = static_cast<size_t>(-1); - - for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) - { - mAppliedTFBuffers[i] = NULL; - mAppliedTFOffsets[i] = 0; - } + mAppliedTFObject = angle::DirtyPointer; memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants11)); memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants11)); @@ -2604,24 +2573,18 @@ bool Renderer11::testDeviceLost() { bool isLost = false; + if (!mDevice) + { + return true; + } + // GetRemovedReason is used to test if the device is removed HRESULT result = mDevice->GetDeviceRemovedReason(); isLost = d3d11::isDeviceLostError(result); if (isLost) { - // Log error if this is a new device lost event - if (mDeviceLost == false) - { - ERR("The D3D11 device was removed: 0x%08X", result); - } - - // ensure we note the device loss -- - // we'll probably get this done again by notifyDeviceLost - // but best to remember it! - // Note that we don't want to clear the device loss status here - // -- this needs to be done by resetDevice - mDeviceLost = true; + ERR("The D3D11 device was removed: 0x%08X", result); } return isLost; @@ -2734,8 +2697,6 @@ bool Renderer11::resetDevice() return false; } - mDeviceLost = false; - return true; } @@ -2975,7 +2936,7 @@ gl::Error Renderer11::copyImageInternal(const gl::Framebuffer *framebuffer, // Convert to the unsized format before calling copyTexture. const gl::InternalFormat &internalFormat = gl::GetInternalFormatInfo(destFormat); ANGLE_TRY(mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, nullptr, - internalFormat.format, GL_NEAREST, false)); + internalFormat.format, GL_NEAREST, false, false, false)); return gl::NoError(); } @@ -2997,7 +2958,7 @@ gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, ANGLE_TRY(copyImageInternal(framebuffer, sourceRect, destFormat, destOffset, destRenderTarget)); - storage11->invalidateSwizzleCacheLevel(level); + storage11->markLevelDirty(level); return gl::NoError(); } @@ -3015,7 +2976,7 @@ gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl ANGLE_TRY(copyImageInternal(framebuffer, sourceRect, destFormat, destOffset, destRenderTarget)); - storage11->invalidateSwizzleCacheLevel(level); + storage11->markLevelDirty(level); return gl::NoError(); } @@ -3033,7 +2994,7 @@ gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl:: ANGLE_TRY(copyImageInternal(framebuffer, sourceRect, destFormat, destOffset, destRenderTarget)); - storage11->invalidateSwizzleCacheLevel(level); + storage11->markLevelDirty(level); return gl::NoError(); } @@ -3050,15 +3011,104 @@ gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const ASSERT(destRenderTarget); ANGLE_TRY(copyImageInternal(framebuffer, sourceRect, destFormat, destOffset, destRenderTarget)); + storage11->markLevelDirty(level); + + return gl::NoError(); +} + +gl::Error Renderer11::copyTexture(const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + const TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source); + + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(const_cast<TextureD3D *>(sourceD3D)->getNativeTexture(&sourceStorage)); + + TextureStorage11_2D *sourceStorage11 = GetAs<TextureStorage11_2D>(sourceStorage); + ASSERT(sourceStorage11); + + TextureStorage11_2D *destStorage11 = GetAs<TextureStorage11_2D>(storage); + ASSERT(destStorage11); + + // Check for fast path where a CopySubresourceRegion can be used. + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !unpackFlipY && + sourceStorage11->getFormatSet().texFormat == destStorage11->getFormatSet().texFormat) + { + ID3D11Resource *sourceResource = nullptr; + ANGLE_TRY(sourceStorage11->getResource(&sourceResource)); + + gl::ImageIndex sourceIndex = gl::ImageIndex::Make2D(sourceLevel); + UINT sourceSubresource = sourceStorage11->getSubresourceIndex(sourceIndex); - storage11->invalidateSwizzleCacheLevel(level); + ID3D11Resource *destResource = nullptr; + ANGLE_TRY(destStorage11->getResource(&destResource)); + + gl::ImageIndex destIndex = gl::ImageIndex::Make2D(destLevel); + UINT destSubresource = destStorage11->getSubresourceIndex(destIndex); + + D3D11_BOX sourceBox{ + static_cast<UINT>(sourceRect.x), + static_cast<UINT>(sourceRect.y), + 0u, + static_cast<UINT>(sourceRect.x + sourceRect.width), + static_cast<UINT>(sourceRect.y + sourceRect.height), + 1u, + }; + + mDeviceContext->CopySubresourceRegion(destResource, destSubresource, destOffset.x, + destOffset.y, destOffset.z, sourceResource, + sourceSubresource, &sourceBox); + } + else + { + ID3D11ShaderResourceView *sourceSRV = nullptr; + ANGLE_TRY(sourceStorage11->getSRVLevels(sourceLevel, sourceLevel, &sourceSRV)); + + gl::ImageIndex destIndex = gl::ImageIndex::Make2D(destLevel); + RenderTargetD3D *destRenderTargetD3D = nullptr; + ANGLE_TRY(destStorage11->getRenderTarget(destIndex, &destRenderTargetD3D)); + + RenderTarget11 *destRenderTarget11 = GetAs<RenderTarget11>(destRenderTargetD3D); + + ID3D11RenderTargetView *destRTV = destRenderTarget11->getRenderTargetView(); + ASSERT(destRTV); + + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize( + static_cast<int>(source->getWidth(source->getTarget(), sourceLevel)), + static_cast<int>(source->getHeight(source->getTarget(), sourceLevel)), 1); + if (unpackFlipY) + { + sourceArea.y = sourceSize.height - sourceRect.y; + sourceArea.height = -sourceArea.height; + } + + gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget11->getWidth(), destRenderTarget11->getHeight(), 1); + + // Use nearest filtering because source and destination are the same size for the direct + // copy + ANGLE_TRY(mBlit->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, + nullptr, destFormat, GL_NEAREST, false, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha)); + } + + destStorage11->markLevelDirty(destLevel); return gl::NoError(); } gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) { - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mRenderer11DeviceCaps); + const d3d11::Format &formatInfo = d3d11::Format::Get(format, mRenderer11DeviceCaps); const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format); GLuint supportedSamples = textureCaps.getNearestSamples(samples); @@ -3071,7 +3121,7 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G desc.Height = height; desc.MipLevels = 1; desc.ArraySize = 1; - desc.Format = formatInfo.formatSet->texFormat; + desc.Format = formatInfo.texFormat; desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -3082,19 +3132,22 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G // we'll flag it to allow binding that way. Shader resource views are a little // more complicated. bool bindRTV = false, bindDSV = false, bindSRV = false; - bindRTV = (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN); - bindDSV = (formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN); - if (formatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) + bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); + bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + bindSRV = (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN); + + // D3D feature level 10.0 no longer allows creation of textures with both the bind SRV and + // DSV flags when multisampled. crbug.com/656989 + bool supportsMultisampledDepthStencilSRVs = + mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_10_0; + bool isMultisampledDepthStencil = bindDSV && desc.SampleDesc.Count > 1; + if (isMultisampledDepthStencil && !supportsMultisampledDepthStencilSRVs) { - // Multisample targets flagged for binding as depth stencil cannot also be - // flagged for binding as SRV, so make certain not to add the SRV flag for - // these targets. - bindSRV = !(formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN && - desc.SampleDesc.Count > 1); + bindSRV = false; } - desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | - (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | + desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | + (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); // The format must be either an RTV or a DSV @@ -3113,7 +3166,7 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G if (bindSRV) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = formatInfo.formatSet->srvFormat; + srvDesc.Format = formatInfo.srvFormat; srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; @@ -3126,10 +3179,10 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result); } - if (formatInfo.formatSet->blitSRVFormat != formatInfo.formatSet->srvFormat) + if (formatInfo.blitSRVFormat != formatInfo.srvFormat) { D3D11_SHADER_RESOURCE_VIEW_DESC blitSRVDesc; - blitSRVDesc.Format = formatInfo.formatSet->blitSRVFormat; + blitSRVDesc.Format = formatInfo.blitSRVFormat; blitSRVDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; @@ -3158,7 +3211,7 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G if (bindDSV) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = formatInfo.formatSet->dsvFormat; + dsvDesc.Format = formatInfo.dsvFormat; dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; dsvDesc.Texture2D.MipSlice = 0; dsvDesc.Flags = 0; @@ -3174,16 +3227,15 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result); } - *outRT = - new TextureRenderTarget11(dsv, texture, srv, format, formatInfo.formatSet->format, - width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget11(dsv, texture, srv, format, formatInfo, width, height, + 1, supportedSamples); SafeRelease(dsv); } else if (bindRTV) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = formatInfo.formatSet->rtvFormat; + rtvDesc.Format = formatInfo.rtvFormat; rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.Texture2D.MipSlice = 0; @@ -3204,9 +3256,8 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G mDeviceContext->ClearRenderTargetView(rtv, clearValues); } - *outRT = new TextureRenderTarget11(rtv, texture, srv, blitSRV, format, - formatInfo.formatSet->format, width, height, 1, - supportedSamples); + *outRT = new TextureRenderTarget11(rtv, texture, srv, blitSRV, format, formatInfo, + width, height, 1, supportedSamples); SafeRelease(rtv); } @@ -3221,9 +3272,9 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G } else { - *outRT = new TextureRenderTarget11(static_cast<ID3D11RenderTargetView *>(nullptr), nullptr, - nullptr, nullptr, format, d3d11::ANGLE_FORMAT_NONE, - width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget11( + static_cast<ID3D11RenderTargetView *>(nullptr), nullptr, nullptr, nullptr, format, + d3d11::Format::Get(GL_NONE, mRenderer11DeviceCaps), width, height, 1, supportedSamples); } return gl::Error(GL_NO_ERROR); @@ -3459,7 +3510,8 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const ASSERT(getNativeExtensions().pixelBufferObject); const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mRenderer11DeviceCaps); + const d3d11::Format &d3d11FormatInfo = + d3d11::Format::Get(internalFormat, mRenderer11DeviceCaps); // sRGB formats do not work with D3D11 buffer SRVs if (internalFormatInfo.colorEncoding == GL_SRGB) @@ -3468,7 +3520,7 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const } // We cannot support direct copies to non-color-renderable formats - if (d3d11FormatInfo.formatSet->rtvFormat == DXGI_FORMAT_UNKNOWN) + if (d3d11FormatInfo.rtvFormat == DXGI_FORMAT_UNKNOWN) { return false; } @@ -3480,14 +3532,19 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const } // We don't support formats which we can't represent without conversion - if (d3d11FormatInfo.formatSet->glInternalFormat != internalFormat) + if (d3d11FormatInfo.format.glInternalFormat != internalFormat) + { + return false; + } + + // Buffer SRV creation for this format was not working on Windows 10. + if (d3d11FormatInfo.texFormat == DXGI_FORMAT_B5G5R5A1_UNORM) { return false; } - // Buffer SRV creation in this format was not working on Windows 10, repro at least on Intel - // and NVIDIA. - if (internalFormat == GL_RGB5_A1) + // This format is not supported as a buffer SRV. + if (d3d11FormatInfo.texFormat == DXGI_FORMAT_A8_UNORM) { return false; } @@ -3523,16 +3580,12 @@ gl::Error Renderer11::generateMipmapUsingD3D(TextureStorage *storage, ASSERT(storage11->supportsNativeMipmapFunction()); ID3D11ShaderResourceView *srv; - gl::Error error = storage11->getSRVLevels(textureState.getEffectiveBaseLevel(), - textureState.getEffectiveMaxLevel(), &srv); - if (error.isError()) - { - return error; - } + ANGLE_TRY(storage11->getSRVLevels(textureState.getEffectiveBaseLevel(), + textureState.getEffectiveMaxLevel(), &srv)); mDeviceContext->GenerateMips(srv); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain) @@ -3541,9 +3594,10 @@ TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain) return new TextureStorage11_2D(this, swapChain11); } -TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage) +TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) { - return new TextureStorage11_EGLImage(this, eglImage); + return new TextureStorage11_EGLImage(this, eglImage, GetAs<RenderTarget11>(renderTargetD3D)); } TextureStorage *Renderer11::createTextureStorageExternal( @@ -3593,7 +3647,7 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt ASSERT(rt11->getTexture()); TextureHelper11 textureHelper = - TextureHelper11::MakeAndReference(rt11->getTexture(), rt11->getANGLEFormat()); + TextureHelper11::MakeAndReference(rt11->getTexture(), rt11->getFormatSet()); unsigned int sourceSubResource = rt11->getSubresourceIndex(); const gl::Extents &texSize = textureHelper.getExtents(); @@ -3627,8 +3681,8 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt gl::Extents safeSize(safeArea.width, safeArea.height, 1); TextureHelper11 stagingHelper; ANGLE_TRY_RESULT( - CreateStagingTexture(textureHelper.getTextureType(), textureHelper.getANGLEFormat(), - safeSize, StagingAccess::READ, mDevice), + CreateStagingTexture(textureHelper.getTextureType(), textureHelper.getFormatSet(), safeSize, + StagingAccess::READ, mDevice), stagingHelper); TextureHelper11 resolvedTextureHelper; @@ -3665,7 +3719,7 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt mDeviceContext->ResolveSubresource(resolveTex2D, 0, textureHelper.getTexture2D(), sourceSubResource, textureHelper.getFormat()); resolvedTextureHelper = - TextureHelper11::MakeAndReference(resolveTex2D, textureHelper.getANGLEFormat()); + TextureHelper11::MakeAndReference(resolveTex2D, textureHelper.getFormatSet()); sourceSubResource = 0; srcTexture = &resolvedTextureHelper; @@ -3728,14 +3782,10 @@ gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper, uint8_t *source = static_cast<uint8_t *>(mapping.pData); int inputPitch = static_cast<int>(mapping.RowPitch); - const auto &angleFormatInfo = d3d11::GetANGLEFormatSet(textureHelper.getANGLEFormat()); - const gl::InternalFormat &sourceFormatInfo = - gl::GetInternalFormatInfo(angleFormatInfo.glInternalFormat); - const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureHelper.getFormat()); - ColorReadFunction colorReadFunction = angleFormatInfo.colorReadFunction; + const auto &formatInfo = textureHelper.getFormatSet(); + ASSERT(formatInfo.format.glInternalFormat != GL_NONE); - PackPixels(params, sourceFormatInfo, dxgiFormatInfo.fastCopyFunctions, colorReadFunction, - inputPitch, source, pixelsOut); + PackPixels(params, formatInfo.format, inputPitch, source, pixelsOut); mDeviceContext->Unmap(readResource, 0); @@ -3764,7 +3814,7 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, } TextureHelper11 drawTexture = TextureHelper11::MakeAndReference( - drawRenderTarget11->getTexture(), drawRenderTarget11->getANGLEFormat()); + drawRenderTarget11->getTexture(), drawRenderTarget11->getFormatSet()); unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView(); ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView(); @@ -3784,27 +3834,31 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, auto readRT11 = GetAs<RenderTarget11>(readRenderTarget); ANGLE_TRY_RESULT(resolveMultisampledTexture(readRT11, depthBlit, stencilBlit), readTexture); - const auto &formatSet = d3d11::GetANGLEFormatSet(readTexture.getANGLEFormat()); + if (!stencilBlit) + { + const auto &readFormatSet = readTexture.getFormatSet(); - D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc; - srViewDesc.Format = formatSet.srvFormat; - srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srViewDesc.Texture2D.MipLevels = 1; - srViewDesc.Texture2D.MostDetailedMip = 0; + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + viewDesc.Format = readFormatSet.srvFormat; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MipLevels = 1; + viewDesc.Texture2D.MostDetailedMip = 0; - HRESULT hresult = - mDevice->CreateShaderResourceView(readTexture.getResource(), &srViewDesc, &readSRV); - if (FAILED(hresult)) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Renderer11::blitRenderbufferRect: Failed to create temporary SRV."); + HRESULT hresult = + mDevice->CreateShaderResourceView(readTexture.getResource(), &viewDesc, &readSRV); + if (FAILED(hresult)) + { + return gl::Error( + GL_OUT_OF_MEMORY, + "Renderer11::blitRenderbufferRect: Failed to create temporary SRV."); + } } } else { ASSERT(readRenderTarget11); readTexture = TextureHelper11::MakeAndReference(readRenderTarget11->getTexture(), - readRenderTarget11->getANGLEFormat()); + readRenderTarget11->getFormatSet()); readSubresource = readRenderTarget11->getSubresourceIndex(); readSRV = readRenderTarget11->getBlitShaderResourceView(); if (readSRV == nullptr) @@ -3816,10 +3870,8 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, readSRV->AddRef(); } - if (!readSRV) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target."); - } + // Stencil blits don't use shaders. + ASSERT(readSRV || stencilBlit); const gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); const gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); @@ -3888,22 +3940,21 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, const auto &destFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()); const auto &srcFormatInfo = gl::GetInternalFormatInfo(readRenderTarget->getInternalFormat()); - const auto &formatSet = d3d11::GetANGLEFormatSet(drawRenderTarget11->getANGLEFormat()); - const DXGI_FORMAT drawDXGIFormat = colorBlit ? formatSet.rtvFormat : formatSet.dsvFormat; - const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawDXGIFormat); + const auto &formatSet = drawRenderTarget11->getFormatSet(); + const auto &nativeFormat = formatSet.format; // Some blits require masking off emulated texture channels. eg: from RGBA8 to RGB8, we // emulate RGB8 with RGBA8, so we need to mask off the alpha channel when we copy. gl::Color<bool> colorMask; - colorMask.red = (srcFormatInfo.redBits > 0) && (destFormatInfo.redBits == 0) && - (dxgiFormatInfo.redBits > 0); + colorMask.red = + (srcFormatInfo.redBits > 0) && (destFormatInfo.redBits == 0) && (nativeFormat.redBits > 0); colorMask.green = (srcFormatInfo.greenBits > 0) && (destFormatInfo.greenBits == 0) && - (dxgiFormatInfo.greenBits > 0); + (nativeFormat.greenBits > 0); colorMask.blue = (srcFormatInfo.blueBits > 0) && (destFormatInfo.blueBits == 0) && - (dxgiFormatInfo.blueBits > 0); + (nativeFormat.blueBits > 0); colorMask.alpha = (srcFormatInfo.alphaBits > 0) && (destFormatInfo.alphaBits == 0) && - (dxgiFormatInfo.alphaBits > 0); + (nativeFormat.alphaBits > 0); // We only currently support masking off the alpha channel. bool colorMaskingNeeded = colorMask.alpha; @@ -3924,9 +3975,11 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; - bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit); + bool partialDSBlit = + (nativeFormat.depthBits > 0 && depthBlit) != (nativeFormat.stencilBits > 0 && stencilBlit); - if (readRenderTarget11->getANGLEFormat() == drawRenderTarget11->getANGLEFormat() && + if (readRenderTarget11->getFormatSet().format.id == + drawRenderTarget11->getFormatSet().format.id && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && !colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy)) { @@ -3987,6 +4040,7 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, } else if (depthBlit) { + ASSERT(readSRV); ANGLE_TRY(mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize, scissor)); } @@ -4000,8 +4054,10 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, { // We don't currently support masking off any other channel than alpha bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha; + ASSERT(readSRV); ANGLE_TRY(mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, - scissor, destFormatInfo.format, filter, maskOffAlpha)); + scissor, destFormatInfo.format, filter, maskOffAlpha, + false, false)); } } @@ -4058,12 +4114,17 @@ void Renderer11::onBufferDelete(const Buffer11 *deleted) gl::ErrorOrResult<TextureHelper11> Renderer11::resolveMultisampledTexture(RenderTarget11 *renderTarget, bool depth, bool stencil) { - if (depth || stencil) + if (depth && !stencil) { - return mBlit->resolveDepthStencil(renderTarget, depth, stencil); + return mBlit->resolveDepth(renderTarget); } - const auto &formatSet = d3d11::GetANGLEFormatSet(renderTarget->getANGLEFormat()); + if (stencil) + { + return mBlit->resolveStencil(renderTarget, depth); + } + + const auto &formatSet = renderTarget->getFormatSet(); ASSERT(renderTarget->getSamples() > 1); @@ -4090,7 +4151,7 @@ Renderer11::resolveMultisampledTexture(RenderTarget11 *renderTarget, bool depth, mDeviceContext->ResolveSubresource(resolveTexture, 0, renderTarget->getTexture(), renderTarget->getSubresourceIndex(), formatSet.texFormat); - return TextureHelper11::MakeAndPossess2D(resolveTexture, renderTarget->getANGLEFormat()); + return TextureHelper11::MakeAndPossess2D(resolveTexture, renderTarget->getFormatSet()); } bool Renderer11::getLUID(LUID *adapterLuid) const @@ -4168,7 +4229,7 @@ void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureC WorkaroundsD3D Renderer11::generateWorkarounds() const { - return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps.featureLevel); + return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription); } gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) @@ -4232,7 +4293,7 @@ gl::Error Renderer11::genericDrawElements(Context11 *context, ANGLE_TRY(applyIndexBuffer(data, indices, count, mode, type, &indexInfo)); - applyTransformFeedbackBuffers(glState); + applyTransformFeedbackBuffers(data); // Transform feedback is not allowed for DrawElements, this error should have been caught at the // API validation layer. ASSERT(!glState.isTransformFeedbackActiveUnpaused()); @@ -4274,7 +4335,7 @@ gl::Error Renderer11::genericDrawArrays(Context11 *context, } ANGLE_TRY(updateState(data, mode)); - ANGLE_TRY(applyTransformFeedbackBuffers(glState)); + ANGLE_TRY(applyTransformFeedbackBuffers(data)); ANGLE_TRY(applyVertexBuffer(glState, mode, first, count, instances, nullptr)); ANGLE_TRY(applyTextures(context, data)); ANGLE_TRY(applyShaders(data, mode)); @@ -4328,6 +4389,11 @@ gl::Error Renderer11::getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer return gl::NoError(); } +gl::Version Renderer11::getMaxSupportedESVersion() const +{ + return gl::Version(d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps.featureLevel), 0); +} + gl::DebugAnnotator *Renderer11::getAnnotator() { return mAnnotator; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h index f86ae6e2c5a..b19c5dc09d6 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h @@ -52,6 +52,7 @@ struct Renderer11DeviceCaps UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM + Optional<LARGE_INTEGER> driverVersion; // Four-part driver version number. }; enum @@ -105,7 +106,7 @@ class Renderer11 : public RendererD3D virtual ~Renderer11(); egl::Error initialize() override; - virtual bool resetDevice(); + bool resetDevice() override; egl::ConfigSet generateConfigs() override; void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; @@ -126,8 +127,11 @@ class Renderer11 : public RendererD3D GLenum depthBufferFormat, EGLint orientation) override; - virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); + gl::Error setSamplerState(gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler) override; + gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) override; gl::Error setUniformBuffers(const gl::ContextState &data, const std::vector<GLint> &vertexUniformBuffers, @@ -152,11 +156,11 @@ class Renderer11 : public RendererD3D GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - gl::Error applyTransformFeedbackBuffers(const gl::State &state); + gl::Error applyTransformFeedbackBuffers(const gl::ContextState &data); // lost device bool testDeviceLost() override; - bool testDeviceResettable(); + bool testDeviceResettable() override; std::string getRendererDescription() const; DeviceIdentifier getAdapterIdentifier() const override; @@ -170,7 +174,7 @@ class Renderer11 : public RendererD3D bool getNV12TextureSupport() const; - virtual int getMajorShaderModel() const; + int getMajorShaderModel() const override; int getMinorShaderModel() const override; std::string getShaderModelSuffix() const override; @@ -201,6 +205,17 @@ class Renderer11 : public RendererD3D TextureStorage *storage, GLint level) override; + gl::Error copyTexture(const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + // RenderTarget creation gl::Error createRenderTarget(int width, int height, @@ -231,7 +246,8 @@ class Renderer11 : public RendererD3D gl::Error generateMipmapUsingD3D(TextureStorage *storage, const gl::TextureState &textureState) override; TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override; - TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) override; TextureStorage *createTextureStorageExternal( egl::Stream *stream, const egl::Stream::GLTextureDescription &desc) override; @@ -281,9 +297,13 @@ class Renderer11 : public RendererD3D gl::DebugAnnotator *getAnnotator(); // Buffer-to-texture and Texture-to-buffer copies - virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override; + gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) override; void markAllStateDirty(); gl::Error packPixels(const TextureHelper11 &textureHelper, @@ -341,6 +361,8 @@ class Renderer11 : public RendererD3D gl::Error getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut); + gl::Version getMaxSupportedESVersion() const override; + protected: gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; @@ -470,15 +492,7 @@ class Renderer11 : public RendererD3D bool mAppliedIBChanged; // Currently applied transform feedback buffers - size_t mAppliedNumXFBBindings; - ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current D3D buffers - // in use for streamout - GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current GL-specified - // buffer offsets to transform feedback - // buffers - UINT mCurrentD3DOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the D3D buffer offsets, - // which may differ from GLs, due - // to different append behavior + uintptr_t mAppliedTFObject; // Currently applied shaders uintptr_t mAppliedVertexShader; @@ -549,5 +563,5 @@ class Renderer11 : public RendererD3D mutable Optional<bool> mSupportsShareHandles; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp index d00d831c737..0e28c8c18a0 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp @@ -24,15 +24,16 @@ namespace bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc) { unsigned mipLevel = index.mipIndex; - unsigned layerIndex = index.layerIndex; + GLint layerIndex = index.layerIndex; GLenum type = index.type; switch (desc.ViewDimension) { case D3D11_SRV_DIMENSION_TEXTURE2D: { - unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip; - maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip; + bool allLevels = (desc.Texture2D.MipLevels == std::numeric_limits<UINT>::max()); + unsigned int maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; unsigned mipMin = index.mipIndex; unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex; @@ -44,22 +45,25 @@ bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOUR case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: { - unsigned maxSrvMip = + bool allLevels = (desc.Texture2DArray.MipLevels == std::numeric_limits<UINT>::max()); + unsigned int maxSrvMip = desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip; - maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize; // Cube maps can be mapped to Texture2DArray SRVs return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) && desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip && - desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice; + desc.Texture2DArray.FirstArraySlice <= static_cast<UINT>(layerIndex) && + static_cast<UINT>(layerIndex) < maxSlice; } case D3D11_SRV_DIMENSION_TEXTURECUBE: { - unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip; - maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip; + bool allLevels = (desc.TextureCube.MipLevels == std::numeric_limits<UINT>::max()); + unsigned int maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; return gl::IsCubeMapTextureTarget(type) && desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; @@ -67,8 +71,9 @@ bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOUR case D3D11_SRV_DIMENSION_TEXTURE3D: { - unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip; - maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip; + bool allLevels = (desc.Texture3D.MipLevels == std::numeric_limits<UINT>::max()); + unsigned int maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; return type == GL_TEXTURE_3D && desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; @@ -487,16 +492,11 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, { if (!mBlendStateIsDirty && sampleMask == mCurSampleMask) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ID3D11BlendState *dxBlendState = nullptr; - gl::Error error = - mRenderer->getStateCache().getBlendState(framebuffer, blendState, &dxBlendState); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->getStateCache().getBlendState(framebuffer, blendState, &dxBlendState)); ASSERT(dxBlendState != nullptr); @@ -527,7 +527,7 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, mBlendStateIsDirty = false; - return error; + return gl::NoError(); } gl::Error StateManager11::setDepthStencilState(const gl::State &glState) @@ -547,7 +547,7 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) disableDepth == mCurDisableDepth.value() && mCurDisableStencil.valid() && disableStencil == mCurDisableStencil.value()) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } const auto &depthStencilState = glState.getDepthStencilState(); @@ -567,12 +567,8 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) (depthStencilState.stencilBackMask & maxStencil)); ID3D11DepthStencilState *dxDepthStencilState = NULL; - gl::Error error = mRenderer->getStateCache().getDepthStencilState( - depthStencilState, disableDepth, disableStencil, &dxDepthStencilState); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->getStateCache().getDepthStencilState( + depthStencilState, disableDepth, disableStencil, &dxDepthStencilState)); ASSERT(dxDepthStencilState); @@ -596,7 +592,7 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) mDepthStencilStateIsDirty = false; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterState) @@ -605,11 +601,10 @@ gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterSt if (!mRasterizerStateIsDirty && rasterState.pointDrawMode == mCurRasterState.pointDrawMode && rasterState.multiSample == mCurRasterState.multiSample) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ID3D11RasterizerState *dxRasterState = nullptr; - gl::Error error(GL_NO_ERROR); if (mCurPresentPathFastEnabled) { @@ -628,18 +623,13 @@ gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterSt modifiedRasterState.frontFace = GL_CCW; } - error = mRenderer->getStateCache().getRasterizerState(modifiedRasterState, - mCurScissorEnabled, &dxRasterState); + ANGLE_TRY(mRenderer->getStateCache().getRasterizerState( + modifiedRasterState, mCurScissorEnabled, &dxRasterState)); } else { - error = mRenderer->getStateCache().getRasterizerState(rasterState, mCurScissorEnabled, - &dxRasterState); - } - - if (error.isError()) - { - return error; + ANGLE_TRY(mRenderer->getStateCache().getRasterizerState(rasterState, mCurScissorEnabled, + &dxRasterState)); } mRenderer->getDeviceContext()->RSSetState(dxRasterState); @@ -647,7 +637,7 @@ gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterSt mCurRasterState = rasterState; mRasterizerStateIsDirty = false; - return error; + return gl::NoError(); } void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) @@ -862,7 +852,7 @@ gl::Error StateManager11::onMakeCurrent(const gl::ContextState &data) } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void StateManager11::setShaderResource(gl::SamplerType shaderType, @@ -896,7 +886,7 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, { if (rangeStart == rangeEnd) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } auto ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); @@ -906,7 +896,7 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, if (clearRange.empty()) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } auto deviceContext = mRenderer->getDeviceContext(); @@ -928,7 +918,7 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, currentSRVs.update(samplerIndex, nullptr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType, @@ -984,11 +974,7 @@ void StateManager11::deinitialize() gl::Error StateManager11::syncFramebuffer(gl::Framebuffer *framebuffer) { Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer); - gl::Error error = framebuffer11->invalidateSwizzles(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(framebuffer11->markAttachmentsDirty()); if (framebuffer11->hasAnyInternalDirtyBit()) { @@ -998,7 +984,7 @@ gl::Error StateManager11::syncFramebuffer(gl::Framebuffer *framebuffer) if (!mRenderTargetIsDirty) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } mRenderTargetIsDirty = false; @@ -1012,7 +998,7 @@ gl::Error StateManager11::syncFramebuffer(gl::Framebuffer *framebuffer) const gl::Extents &size = framebuffer->getFirstColorbuffer()->getSize(); if (size.width == 0 || size.height == 0) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } @@ -1096,7 +1082,7 @@ gl::Error StateManager11::syncFramebuffer(gl::Framebuffer *framebuffer) setViewportBounds(renderTargetWidth, renderTargetHeight); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error StateManager11::updateCurrentValueAttribs(const gl::State &state, @@ -1119,15 +1105,11 @@ gl::Error StateManager11::updateCurrentValueAttribs(const gl::State &state, currentValueAttrib->currentValueType = currentValue.Type; currentValueAttrib->attribute = &vertexAttributes[attribIndex]; - gl::Error error = vertexDataManager->storeCurrentValue(currentValue, currentValueAttrib, - static_cast<size_t>(attribIndex)); - if (error.isError()) - { - return error; - } + ANGLE_TRY(vertexDataManager->storeCurrentValue(currentValue, currentValueAttrib, + static_cast<size_t>(attribIndex))); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } const std::vector<TranslatedAttribute> &StateManager11::getCurrentValueAttribs() const diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp index e934aa888f8..b12fd80d2c6 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -177,7 +177,8 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe releaseOffscreenColorBuffer(); - const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + const d3d11::Format &backbufferFormatInfo = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); // If the app passed in a share handle, open the resource // See EGL_ANGLE_d3d_share_handle_client_buffer @@ -209,7 +210,7 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe if (offscreenTextureDesc.Width != (UINT)backbufferWidth || offscreenTextureDesc.Height != (UINT)backbufferHeight || - offscreenTextureDesc.Format != backbufferFormatInfo.formatSet->texFormat || + offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || offscreenTextureDesc.MipLevels != 1 || offscreenTextureDesc.ArraySize != 1) { ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); @@ -225,7 +226,7 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; - offscreenTextureDesc.Format = backbufferFormatInfo.formatSet->texFormat; + offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; offscreenTextureDesc.SampleDesc.Count = 1; @@ -283,7 +284,7 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe mKeyedMutex = d3d11::DynamicCastComObject<IDXGIKeyedMutex>(mOffscreenTexture); D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; - offscreenRTVDesc.Format = backbufferFormatInfo.formatSet->rtvFormat; + offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; offscreenRTVDesc.Texture2D.MipSlice = 0; @@ -292,7 +293,7 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target"); D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; - offscreenSRVDesc.Format = backbufferFormatInfo.formatSet->srvFormat; + offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; offscreenSRVDesc.Texture2D.MostDetailedMip = 0; offscreenSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1); @@ -333,13 +334,13 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe if (mDepthBufferFormat != GL_NONE) { - const d3d11::TextureFormat &depthBufferFormatInfo = - d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); + const d3d11::Format &depthBufferFormatInfo = + d3d11::Format::Get(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE2D_DESC depthStencilTextureDesc; depthStencilTextureDesc.Width = backbufferWidth; depthStencilTextureDesc.Height = backbufferHeight; - depthStencilTextureDesc.Format = depthBufferFormatInfo.formatSet->texFormat; + depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; depthStencilTextureDesc.SampleDesc.Count = 1; @@ -347,7 +348,7 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - if (depthBufferFormatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) + if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { depthStencilTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; } @@ -375,7 +376,7 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture"); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; - depthStencilDesc.Format = depthBufferFormatInfo.formatSet->dsvFormat; + depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilDesc.Flags = 0; depthStencilDesc.Texture2D.MipSlice = 0; @@ -384,10 +385,10 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe ASSERT(SUCCEEDED(result)); d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view"); - if (depthBufferFormatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) + if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; - depthStencilSRVDesc.Format = depthBufferFormatInfo.formatSet->srvFormat; + depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; depthStencilSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1); @@ -489,7 +490,7 @@ DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const return (mOffscreenRenderTargetFormat == GL_BGRA8_EXT) ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM; } -EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) +EGLint SwapChain11::reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) { mSwapInterval = static_cast<unsigned int>(swapInterval); if (mSwapInterval > 4) @@ -876,4 +877,4 @@ void SwapChain11::recreate() // possibly should use this method instead of reset } -} +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h index 23f2fd37b12..1ea608054b0 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h @@ -18,7 +18,7 @@ namespace rx class Renderer11; class NativeWindow11; -class SwapChain11 : public SwapChainD3D +class SwapChain11 final : public SwapChainD3D { public: SwapChain11(Renderer11 *renderer, @@ -30,20 +30,20 @@ class SwapChain11 : public SwapChainD3D virtual ~SwapChain11(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - virtual void recreate(); + EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) override; + EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) override; + void recreate() override; RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; } RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; } - virtual ID3D11Texture2D *getOffscreenTexture(); - virtual ID3D11RenderTargetView *getRenderTarget(); - virtual ID3D11ShaderResourceView *getRenderTargetShaderResource(); + ID3D11Texture2D *getOffscreenTexture(); + ID3D11RenderTargetView *getRenderTarget(); + ID3D11ShaderResourceView *getRenderTargetShaderResource(); - virtual ID3D11Texture2D *getDepthStencilTexture(); - virtual ID3D11DepthStencilView *getDepthStencil(); - virtual ID3D11ShaderResourceView *getDepthStencilShaderResource(); + ID3D11Texture2D *getDepthStencilTexture(); + ID3D11DepthStencilView *getDepthStencil(); + ID3D11ShaderResourceView *getDepthStencilShaderResource(); EGLint getWidth() const { return mWidth; } EGLint getHeight() const { return mHeight; } @@ -103,5 +103,5 @@ class SwapChain11 : public SwapChainD3D SurfaceRenderTarget11 mDepthStencilRenderTarget; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp index 81c6f39b471..e84aca677ea 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp @@ -31,27 +31,29 @@ namespace rx { -TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle) - : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle) +TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil) + : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil) { } bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const { - return std::tie(baseLevel, mipLevels, swizzle) < - std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle); + return std::tie(baseLevel, mipLevels, swizzle, dropStencil) < + std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil); } -TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags) +TextureStorage11::TextureStorage11(Renderer11 *renderer, + UINT bindFlags, + UINT miscFlags, + GLenum internalFormat) : mRenderer(renderer), mTopLevel(0), mMipLevels(0), - mInternalFormat(GL_NONE), - mTextureFormatSet(nullptr), - mSwizzleFormatSet(nullptr), + mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())), mTextureWidth(0), mTextureHeight(0), mTextureDepth(0), + mDropStencilTexture(nullptr), mBindFlags(bindFlags), mMiscFlags(miscFlags) { @@ -72,6 +74,7 @@ TextureStorage11::~TextureStorage11() SafeRelease(i->second); } mSrvCache.clear(); + SafeRelease(mDropStencilTexture); } DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, @@ -80,17 +83,16 @@ DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, { UINT bindFlags = 0; - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); - if (formatInfo.formatSet->srvFormat != DXGI_FORMAT_UNKNOWN) + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); + if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_SHADER_RESOURCE; } - if (formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) + if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_DEPTH_STENCIL; } - if (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget) + if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget) { bindFlags |= D3D11_BIND_RENDER_TARGET; } @@ -105,12 +107,10 @@ DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, { UINT miscFlags = 0; - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); if (renderTarget && levels > 1) { - const d3d11::DXGIFormat &dxgiFormatInfo = - d3d11::GetDXGIFormatInfo(formatInfo.formatSet->texFormat); + const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); if (dxgiFormatInfo.nativeMipmapSupport(renderer11DeviceCaps.featureLevel)) { @@ -205,11 +205,7 @@ gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState, if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { // We must ensure that the level zero texture is in sync with mipped texture. - gl::Error error = useLevelZeroWorkaroundTexture(mipLevels == 1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(useLevelZeroWorkaroundTexture(mipLevels == 1)); } if (swizzleRequired) @@ -217,7 +213,22 @@ gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState, verifySwizzleExists(textureState.getSwizzleState()); } - SRVKey key(effectiveBaseLevel, mipLevels, swizzleRequired); + // We drop the stencil when sampling from the SRV if three conditions hold: + // 1. the drop stencil workaround is enabled. + bool workaround = mRenderer->getWorkarounds().emulateTinyStencilTextures; + // 2. this is a stencil texture. + bool hasStencil = (mFormatInfo.format.stencilBits > 0); + // 3. the texture has a 1x1 or 2x2 mip. + bool hasSmallMips = (getLevelWidth(mMipLevels - 1) <= 2 || getLevelHeight(mMipLevels - 1) <= 2); + + bool useDropStencil = (workaround && hasStencil && hasSmallMips); + if (useDropStencil) + { + // Ensure drop texture gets re-created, if SRV is cached. + ANGLE_TRY(createDropStencilTexture()); + } + + SRVKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil); ANGLE_TRY(getCachedOrCreateSRV(key, outSRV)); return gl::NoError(); @@ -234,18 +245,28 @@ gl::Error TextureStorage11::getCachedOrCreateSRV(const SRVKey &key, } ID3D11Resource *texture = nullptr; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + if (key.swizzle) { + ASSERT(!key.dropStencil || mFormatInfo.swizzle.format.stencilBits == 0); ANGLE_TRY(getSwizzleTexture(&texture)); + format = mFormatInfo.swizzle.srvFormat; + } + else if (key.dropStencil) + { + ASSERT(mDropStencilTexture); + texture = mDropStencilTexture; + format = DXGI_FORMAT_R32_FLOAT; } else { ANGLE_TRY(getResource(&texture)); + format = mFormatInfo.srvFormat; } ID3D11ShaderResourceView *srv = nullptr; - DXGI_FORMAT format = - (key.swizzle ? mSwizzleFormatSet->srvFormat : mTextureFormatSet->srvFormat); + ANGLE_TRY(createSRV(key.baseLevel, key.mipLevels, format, texture, &srv)); mSrvCache.insert(std::make_pair(key, srv)); @@ -266,8 +287,7 @@ gl::Error TextureStorage11::getSRVLevel(int mipLevel, if (!levelSRVs[mipLevel]) { // Only create a different SRV for blit if blit format is different from regular srv format - if (otherLevelSRVs[mipLevel] && - mTextureFormatSet->srvFormat == mTextureFormatSet->blitSRVFormat) + if (otherLevelSRVs[mipLevel] && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat) { levelSRVs[mipLevel] = otherLevelSRVs[mipLevel]; levelSRVs[mipLevel]->AddRef(); @@ -275,25 +295,17 @@ gl::Error TextureStorage11::getSRVLevel(int mipLevel, else { ID3D11Resource *resource = nullptr; - gl::Error error = getResource(&resource); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getResource(&resource)); DXGI_FORMAT resourceFormat = - blitSRV ? mTextureFormatSet->blitSRVFormat : mTextureFormatSet->srvFormat; - error = createSRV(mipLevel, 1, resourceFormat, resource, &levelSRVs[mipLevel]); - if (error.isError()) - { - return error; - } + blitSRV ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat; + ANGLE_TRY(createSRV(mipLevel, 1, resourceFormat, resource, &levelSRVs[mipLevel])); } } *outSRV = levelSRVs[mipLevel]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, @@ -314,22 +326,20 @@ gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { // We must ensure that the level zero texture is in sync with mipped texture. - gl::Error error = useLevelZeroWorkaroundTexture(mipLevels == 1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(useLevelZeroWorkaroundTexture(mipLevels == 1)); } - SRVKey key(baseLevel, mipLevels, false); + // TODO(jmadill): Assert we don't need to drop stencil. + + SRVKey key(baseLevel, mipLevels, false, false); ANGLE_TRY(getCachedOrCreateSRV(key, outSRV)); return gl::NoError(); } -d3d11::ANGLEFormat TextureStorage11::getANGLEFormat() const +const d3d11::Format &TextureStorage11::getFormatSet() const { - return mTextureFormatSet->format; + return mFormatInfo; } gl::Error TextureStorage11::generateSwizzles(const gl::SwizzleState &swizzleTarget) @@ -341,38 +351,25 @@ gl::Error TextureStorage11::generateSwizzles(const gl::SwizzleState &swizzleTarg { // Need to re-render the swizzle for this level ID3D11ShaderResourceView *sourceSRV = nullptr; - gl::Error error = getSRVLevel(level, true, &sourceSRV); - - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSRVLevel(level, true, &sourceSRV)); ID3D11RenderTargetView *destRTV = nullptr; - error = getSwizzleRenderTarget(level, &destRTV); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSwizzleRenderTarget(level, &destRTV)); gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); Blit11 *blitter = mRenderer->getBlitter(); - error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleTarget)); mSwizzleCache[level] = swizzleTarget; } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel) +void TextureStorage11::markLevelDirty(int mipLevel) { if (mipLevel >= 0 && static_cast<unsigned int>(mipLevel) < ArraySize(mSwizzleCache)) { @@ -380,13 +377,15 @@ void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel) // not a valid swizzle combination mSwizzleCache[mipLevel] = gl::SwizzleState(); } + + SafeRelease(mDropStencilTexture); } -void TextureStorage11::invalidateSwizzleCache() +void TextureStorage11::markDirty() { for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++) { - invalidateSwizzleCacheLevel(mipLevel); + markLevelDirty(mipLevel); } } @@ -399,7 +398,7 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, const GLint level = index.mipIndex; - invalidateSwizzleCacheLevel(level); + markLevelDirty(level); gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); @@ -425,13 +424,13 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, ASSERT(dstTexture); const d3d11::DXGIFormatSize &dxgiFormatSizeInfo = - d3d11::GetDXGIFormatSizeInfo(mTextureFormatSet->texFormat); - if (!fullCopy && mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) + d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat); + if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead Blit11 *blitter = mRenderer->getBlitter(); - TextureHelper11 source = TextureHelper11::MakeAndReference(srcTexture, getANGLEFormat()); - TextureHelper11 dest = TextureHelper11::MakeAndReference(dstTexture, getANGLEFormat()); + TextureHelper11 source = TextureHelper11::MakeAndReference(srcTexture, getFormatSet()); + TextureHelper11 dest = TextureHelper11::MakeAndReference(dstTexture, getFormatSet()); return blitter->copyDepthStencil(source, sourceSubresource, copyArea, texSize, dest, dstSubresource, copyArea, texSize, nullptr); } @@ -461,22 +460,16 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource *dstTexture, ASSERT(dstTexture); ID3D11Resource *srcTexture = nullptr; - gl::Error error(GL_NO_ERROR); // If the zero-LOD workaround is active and we want to update a level greater than zero, then we // should update the mipmapped texture, even if mapmaps are currently disabled. if (index.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - error = getMippedResource(&srcTexture); + ANGLE_TRY(getMippedResource(&srcTexture)); } else { - error = getResource(&srcTexture); - } - - if (error.isError()) - { - return error; + ANGLE_TRY(getResource(&srcTexture)); } ASSERT(srcTexture); @@ -494,7 +487,7 @@ gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource *dstTexture, // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless the // source box is specified. This is okay, since we don't perform CopySubresourceRegion on // depth/stencil textures on 9_3. - ASSERT(mTextureFormatSet->dsvFormat == DXGI_FORMAT_UNKNOWN); + ASSERT(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN); srcBox.left = region.x; srcBox.right = region.x + region.width; srcBox.top = region.y; @@ -515,21 +508,13 @@ gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, { ASSERT(sourceIndex.layerIndex == destIndex.layerIndex); - invalidateSwizzleCacheLevel(destIndex.mipIndex); + markLevelDirty(destIndex.mipIndex); RenderTargetD3D *source = nullptr; - gl::Error error = getRenderTarget(sourceIndex, &source); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getRenderTarget(sourceIndex, &source)); RenderTargetD3D *dest = nullptr; - error = getRenderTarget(destIndex, &dest); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getRenderTarget(destIndex, &dest)); ID3D11ShaderResourceView *sourceSRV = GetAs<RenderTarget11>(source)->getBlitShaderResourceView(); @@ -542,9 +527,10 @@ gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); Blit11 *blitter = mRenderer->getBlitter(); - return blitter->copyTexture( - sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, nullptr, - gl::GetInternalFormatInfo(source->getInternalFormat()).format, GL_LINEAR, false); + return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, + nullptr, + gl::GetInternalFormatInfo(source->getInternalFormat()).format, + GL_LINEAR, false, false, false); } void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState) @@ -557,7 +543,7 @@ void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState) void TextureStorage11::clearSRVCache() { - invalidateSwizzleCache(); + markDirty(); auto iter = mSrvCache.begin(); while (iter != mSrvCache.end()) @@ -585,26 +571,18 @@ gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) ASSERT(destStorage); ID3D11Resource *sourceResouce = nullptr; - gl::Error error = getResource(&sourceResouce); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getResource(&sourceResouce)); TextureStorage11 *dest11 = GetAs<TextureStorage11>(destStorage); ID3D11Resource *destResource = nullptr; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->getResource(&destResource)); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); immediateContext->CopyResource(destResource, sourceResouce); - dest11->invalidateSwizzleCache(); + dest11->markDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11::setData(const gl::ImageIndex &index, @@ -616,6 +594,8 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, { ASSERT(!image->isDirty()); + markLevelDirty(index.mipIndex); + ID3D11Resource *resource = nullptr; ANGLE_TRY(getResource(&resource)); ASSERT(resource); @@ -644,19 +624,17 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength), srcRowPitch); GLuint srcDepthPitch = 0; - ANGLE_TRY_RESULT(internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment, - unpack.rowLength, unpack.imageHeight), + ANGLE_TRY_RESULT(internalFormatInfo.computeDepthPitch(height, unpack.imageHeight, srcRowPitch), srcDepthPitch); GLuint srcSkipBytes = 0; ANGLE_TRY_RESULT( - internalFormatInfo.computeSkipBytes(srcRowPitch, srcDepthPitch, unpack.skipImages, - unpack.skipRows, unpack.skipPixels, index.is3D()), + internalFormatInfo.computeSkipBytes(srcRowPitch, srcDepthPitch, unpack, index.is3D()), srcSkipBytes); - const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo( - image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps()); + const d3d11::Format &d3d11Format = + d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps()); const d3d11::DXGIFormatSize &dxgiFormatInfo = - d3d11::GetDXGIFormatSizeInfo(d3d11Format.formatSet->texFormat); + d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat); const size_t outputPixelSize = dxgiFormatInfo.pixelBytes; @@ -667,7 +645,7 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, MemoryBuffer *conversionBuffer = nullptr; const uint8_t *data = nullptr; - d3d11::LoadImageFunctionInfo loadFunctionInfo = d3d11Format.loadFunctions.at(type); + LoadImageFunctionInfo loadFunctionInfo = d3d11Format.loadFunctions(type); if (loadFunctionInfo.requiresConversion) { ANGLE_TRY(mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer)); @@ -709,8 +687,17 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, return gl::NoError(); } +gl::Error TextureStorage11::createDropStencilTexture() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, "Drop stencil texture not implemented."); +} + TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0), + : TextureStorage11(renderer, + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, + 0, + swapchain->getRenderTargetInternalFormat()), mTexture(swapchain->getOffscreenTexture()), mLevelZeroTexture(nullptr), mLevelZeroRenderTarget(nullptr), @@ -733,13 +720,6 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swap mTextureHeight = texDesc.Height; mTextureDepth = 1; mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; - - mInternalFormat = swapchain->GetRenderTargetInternalFormat(); - - const auto &formatInfo = - d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - mTextureFormatSet = formatInfo.formatSet; - mSwizzleFormatSet = formatInfo.swizzleFormatSet; } TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, @@ -755,7 +735,8 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, - levels)), + levels), + internalformat), mTexture(nullptr), mHasKeyedMutex(false), mLevelZeroTexture(nullptr), @@ -770,14 +751,7 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, mSwizzleRenderTargets[i] = nullptr; } - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormatSet = formatInfo.formatSet; - mSwizzleFormatSet = formatInfo.swizzleFormatSet; - - d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &width, &height, &mTopLevel); + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); mMipLevels = mTopLevel + levels; mTextureWidth = width; mTextureHeight = height; @@ -842,63 +816,37 @@ gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage) // corresponding textures in destStorage. if (mTexture) { - gl::Error error = dest11->useLevelZeroWorkaroundTexture(false); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(false)); ID3D11Resource *destResource = nullptr; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->getResource(&destResource)); immediateContext->CopyResource(destResource, mTexture); } if (mLevelZeroTexture) { - gl::Error error = dest11->useLevelZeroWorkaroundTexture(true); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(true)); ID3D11Resource *destResource = nullptr; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->getResource(&destResource)); immediateContext->CopyResource(destResource, mLevelZeroTexture); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - else - { - ID3D11Resource *sourceResouce = nullptr; - gl::Error error = getResource(&sourceResouce); - if (error.isError()) - { - return error; - } - ID3D11Resource *destResource = nullptr; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + ID3D11Resource *sourceResouce = nullptr; + ANGLE_TRY(getResource(&sourceResouce)); - immediateContext->CopyResource(destResource, sourceResouce); - dest11->invalidateSwizzleCache(); - } + ID3D11Resource *destResource = nullptr; + ANGLE_TRY(dest11->getResource(&destResource)); - return gl::Error(GL_NO_ERROR); + immediateContext->CopyResource(destResource, sourceResouce); + dest11->markDirty(); + + return gl::NoError(); } gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) @@ -909,11 +857,7 @@ gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTe { if (!mUseLevelZeroTexture && mTexture) { - gl::Error error = ensureTextureExists(1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(1)); // Pull data back from the mipped texture if necessary. ASSERT(mLevelZeroTexture); @@ -927,11 +871,7 @@ gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTe { if (mUseLevelZeroTexture && mLevelZeroTexture) { - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(mMipLevels)); // Pull data back from the level zero texture if necessary. ASSERT(mTexture); @@ -958,7 +898,7 @@ gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTe } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index) @@ -1040,33 +980,23 @@ gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &inde } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource) { if (mUseLevelZeroTexture && mMipLevels > 1) { - gl::Error error = ensureTextureExists(1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(1)); *outResource = mLevelZeroTexture; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - else - { - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } - *outResource = mTexture; - return gl::Error(GL_NO_ERROR); - } + ANGLE_TRY(ensureTextureExists(mMipLevels)); + + *outResource = mTexture; + return gl::NoError(); } gl::Error TextureStorage11_2D::getMippedResource(ID3D11Resource **outResource) @@ -1074,14 +1004,10 @@ gl::Error TextureStorage11_2D::getMippedResource(ID3D11Resource **outResource) // This shouldn't be called unless the zero max LOD workaround is active. ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround); - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(mMipLevels)); *outResource = mTexture; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11_2D::ensureTextureExists(int mipLevels) @@ -1105,7 +1031,7 @@ gl::Error TextureStorage11_2D::ensureTextureExists(int mipLevels) desc.Height = mTextureHeight; desc.MipLevels = mipLevels; desc.ArraySize = 1; - desc.Format = mTextureFormatSet->texFormat; + desc.Format = mFormatInfo.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -1155,29 +1081,17 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend if (mRenderTarget[level]) { *outRT = mRenderTarget[level]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ID3D11Resource *texture = nullptr; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getResource(&texture)); ID3D11ShaderResourceView *srv = nullptr; - error = getSRVLevel(level, false, &srv); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSRVLevel(level, false, &srv)); ID3D11ShaderResourceView *blitSRV = nullptr; - error = getSRVLevel(level, true, &blitSRV); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSRVLevel(level, true, &blitSRV)); ID3D11Device *device = mRenderer->getDevice(); @@ -1186,7 +1100,7 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend if (!mLevelZeroRenderTarget) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + level; @@ -1203,21 +1117,21 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend ASSERT(SUCCEEDED(result)); mLevelZeroRenderTarget = new TextureRenderTarget11( - rtv, mLevelZeroTexture, nullptr, nullptr, mInternalFormat, - mTextureFormatSet->format, getLevelWidth(level), getLevelHeight(level), 1, 0); + rtv, mLevelZeroTexture, nullptr, nullptr, mFormatInfo.internalFormat, + getFormatSet(), getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); } *outRT = mLevelZeroRenderTarget; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - if (mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + level; @@ -1234,7 +1148,7 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend } mRenderTarget[level] = new TextureRenderTarget11( - rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + rtv, texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources @@ -1244,10 +1158,10 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend return gl::Error(GL_NO_ERROR); } - ASSERT(mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN); + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mTextureFormatSet->dsvFormat; + dsvDesc.Format = mFormatInfo.dsvFormat; dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; dsvDesc.Texture2D.MipSlice = mTopLevel + level; dsvDesc.Flags = 0; @@ -1265,14 +1179,14 @@ gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, Rend } mRenderTarget[level] = - new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, mTextureFormatSet->format, + new TextureRenderTarget11(dsv, texture, srv, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(dsv); *outRT = mRenderTarget[level]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11_2D::createSRV(int baseLevel, @@ -1340,7 +1254,7 @@ gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture) desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; desc.ArraySize = 1; - desc.Format = mSwizzleFormatSet->texFormat; + desc.Format = mFormatInfo.swizzle.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -1381,7 +1295,7 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.swizzle.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; @@ -1398,14 +1312,48 @@ gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11Render } *outRTV = mSwizzleRenderTargets[mipLevel]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error TextureStorage11_2D::createDropStencilTexture() +{ + if (mDropStencilTexture) + { + return gl::NoError(); + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = 1; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = 0; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + ID3D11Device *device = mRenderer->getDevice(); + + HRESULT hr = device->CreateTexture2D(&dropDesc, nullptr, &mDropStencilTexture); + if (FAILED(hr)) + { + return gl::Error(GL_INVALID_OPERATION, "Error creating drop stencil texture."); + } + d3d11::SetDebugName(mDropStencilTexture, "TexStorage2D.DropStencil"); + + ANGLE_TRY(initDropStencilTexture(gl::ImageIndexIterator::Make2D(0, mMipLevels))); + + return gl::NoError(); } TextureStorage11_External::TextureStorage11_External( Renderer11 *renderer, egl::Stream *stream, const egl::Stream::GLTextureDescription &glDesc) - : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0) + : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat) { ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11TextureNV12); StreamProducerNV12 *producer = static_cast<StreamProducerNV12 *>(stream->getImplementation()); @@ -1419,13 +1367,7 @@ TextureStorage11_External::TextureStorage11_External( mTextureWidth = desc.Width; mTextureHeight = desc.Height; mTextureDepth = 1; - mInternalFormat = glDesc.internalFormat; mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; - - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(mInternalFormat, renderer->getRenderer11DeviceCaps()); - mTextureFormatSet = formatInfo.formatSet; - mSwizzleFormatSet = formatInfo.swizzleFormatSet; } TextureStorage11_External::~TextureStorage11_External() @@ -1554,25 +1496,24 @@ gl::Error TextureStorage11_External::getSwizzleRenderTarget(int mipLevel, return gl::Error(GL_INVALID_OPERATION); } -TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0), +TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, + EGLImageD3D *eglImage, + RenderTarget11 *renderTarget11) + : TextureStorage11(renderer, + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, + 0, + renderTarget11->getInternalFormat()), mImage(eglImage), mCurrentRenderTarget(0), mSwizzleTexture(nullptr), mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS, nullptr) { - RenderTargetD3D *renderTargetD3D = nullptr; - mImage->getRenderTarget(&renderTargetD3D); - RenderTarget11 *renderTarget11 = GetAs<RenderTarget11>(renderTargetD3D); - mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11); + mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11); mMipLevels = 1; - mTextureFormatSet = &d3d11::GetANGLEFormatSet(renderTarget11->getANGLEFormat()); - mSwizzleFormatSet = &d3d11::GetANGLEFormatSet(mTextureFormatSet->swizzleFormat); mTextureWidth = renderTarget11->getWidth(); mTextureHeight = renderTarget11->getHeight(); mTextureDepth = 1; - mInternalFormat = renderTarget11->getInternalFormat(); } TextureStorage11_EGLImage::~TextureStorage11_EGLImage() @@ -1586,32 +1527,18 @@ TextureStorage11_EGLImage::~TextureStorage11_EGLImage() gl::Error TextureStorage11_EGLImage::getResource(ID3D11Resource **outResource) { - gl::Error error = checkForUpdatedRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(checkForUpdatedRenderTarget()); RenderTarget11 *renderTarget11 = nullptr; - error = getImageRenderTarget(&renderTarget11); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(getImageRenderTarget(&renderTarget11)); *outResource = renderTarget11->getTexture(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11_EGLImage::getSRV(const gl::TextureState &textureState, ID3D11ShaderResourceView **outSRV) { - gl::Error error = checkForUpdatedRenderTarget(); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(checkForUpdatedRenderTarget()); return TextureStorage11::getSRV(textureState, outSRV); } @@ -1660,7 +1587,7 @@ gl::Error TextureStorage11_EGLImage::copyToStorage(TextureStorage *destStorage) ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); immediateContext->CopyResource(destResource, sourceResouce); - dest11->invalidateSwizzleCache(); + dest11->markDirty(); return gl::Error(GL_NO_ERROR); } @@ -1702,7 +1629,7 @@ gl::Error TextureStorage11_EGLImage::getSwizzleTexture(ID3D11Resource **outTextu desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; desc.ArraySize = 1; - desc.Format = mSwizzleFormatSet->texFormat; + desc.Format = mFormatInfo.swizzle.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -1744,7 +1671,7 @@ gl::Error TextureStorage11_EGLImage::getSwizzleRenderTarget(int mipLevel, ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.swizzle.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; @@ -1767,11 +1694,7 @@ gl::Error TextureStorage11_EGLImage::getSwizzleRenderTarget(int mipLevel, gl::Error TextureStorage11_EGLImage::checkForUpdatedRenderTarget() { RenderTarget11 *renderTarget11 = nullptr; - gl::Error error = getImageRenderTarget(&renderTarget11); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getImageRenderTarget(&renderTarget11)); if (mCurrentRenderTarget != reinterpret_cast<uintptr_t>(renderTarget11)) { @@ -1779,7 +1702,7 @@ gl::Error TextureStorage11_EGLImage::checkForUpdatedRenderTarget() mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11_EGLImage::createSRV(int baseLevel, @@ -1836,14 +1759,9 @@ gl::Error TextureStorage11_EGLImage::createSRV(int baseLevel, gl::Error TextureStorage11_EGLImage::getImageRenderTarget(RenderTarget11 **outRT) const { RenderTargetD3D *renderTargetD3D = nullptr; - gl::Error error = mImage->getRenderTarget(&renderTargetD3D); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(mImage->getRenderTarget(&renderTargetD3D)); *outRT = GetAs<RenderTarget11>(renderTargetD3D); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, @@ -1858,7 +1776,8 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, - levels)), + levels), + internalformat), mTexture(nullptr), mLevelZeroTexture(nullptr), mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), @@ -1879,16 +1798,9 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, mLevelZeroRenderTarget[face] = nullptr; } - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormatSet = formatInfo.formatSet; - mSwizzleFormatSet = formatInfo.swizzleFormatSet; - // adjust size if needed for compressed textures int height = size; - d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &size, &height, &mTopLevel); + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel); mMipLevels = mTopLevel + levels; mTextureWidth = size; @@ -2028,7 +1940,7 @@ gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage) immediateContext->CopyResource(destResource, sourceResouce); } - dest11->invalidateSwizzleCache(); + dest11->markDirty(); return gl::Error(GL_NO_ERROR); } @@ -2091,11 +2003,11 @@ void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); + ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(CUBE_FACE_COUNT)); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) + if (0 <= layerTarget && layerTarget < static_cast<GLint>(CUBE_FACE_COUNT)) { mAssociatedImages[layerTarget][level] = image; } @@ -2110,7 +2022,7 @@ bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) + if (0 <= layerTarget && layerTarget < static_cast<GLint>(CUBE_FACE_COUNT)) { // This validation check should never return false. It means the Image/TextureStorage // association is broken. @@ -2130,11 +2042,11 @@ void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); + ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(CUBE_FACE_COUNT)); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) + if (0 <= layerTarget && layerTarget < static_cast<GLint>(CUBE_FACE_COUNT)) { ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); @@ -2155,11 +2067,11 @@ gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &in const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); + ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(CUBE_FACE_COUNT)); if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) + if (0 <= layerTarget && layerTarget < static_cast<GLint>(CUBE_FACE_COUNT)) { // No need to let the old Image recover its data, if it is also the incoming Image. if (mAssociatedImages[layerTarget][level] != nullptr && @@ -2251,7 +2163,7 @@ gl::Error TextureStorage11_Cube::ensureTextureExists(int mipLevels) desc.Height = mTextureHeight; desc.MipLevels = mipLevels; desc.ArraySize = CUBE_FACE_COUNT; - desc.Format = mTextureFormatSet->texFormat; + desc.Format = mFormatInfo.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -2324,7 +2236,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, const int level = index.mipIndex; ASSERT(level >= 0 && level < getLevelCount()); - ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT); + ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(CUBE_FACE_COUNT)); if (!mRenderTarget[faceIndex][level]) { @@ -2343,7 +2255,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, if (!mLevelZeroRenderTarget[faceIndex]) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; @@ -2362,8 +2274,8 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, ASSERT(SUCCEEDED(result)); mLevelZeroRenderTarget[faceIndex] = new TextureRenderTarget11( - rtv, mLevelZeroTexture, nullptr, nullptr, mInternalFormat, - mTextureFormatSet->format, getLevelWidth(level), getLevelHeight(level), 1, 0); + rtv, mLevelZeroTexture, nullptr, nullptr, mFormatInfo.internalFormat, + getFormatSet(), getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources SafeRelease(rtv); @@ -2375,16 +2287,15 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, } ID3D11ShaderResourceView *srv = nullptr; - error = createRenderTargetSRV(texture, index, mTextureFormatSet->srvFormat, &srv); + error = createRenderTargetSRV(texture, index, mFormatInfo.srvFormat, &srv); if (error.isError()) { return error; } ID3D11ShaderResourceView *blitSRV = nullptr; - if (mTextureFormatSet->blitSRVFormat != mTextureFormatSet->srvFormat) + if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) { - error = - createRenderTargetSRV(texture, index, mTextureFormatSet->blitSRVFormat, &blitSRV); + error = createRenderTargetSRV(texture, index, mFormatInfo.blitSRVFormat, &blitSRV); if (error.isError()) { SafeRelease(srv); @@ -2399,10 +2310,10 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, d3d11::SetDebugName(srv, "TexStorageCube.RenderTargetSRV"); - if (mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; @@ -2425,7 +2336,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, d3d11::SetDebugName(rtv, "TexStorageCube.RenderTargetRTV"); mRenderTarget[faceIndex][level] = new TextureRenderTarget11( - rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + rtv, texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources @@ -2433,10 +2344,10 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, SafeRelease(srv); SafeRelease(blitSRV); } - else if (mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) + else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mTextureFormatSet->dsvFormat; + dsvDesc.Format = mFormatInfo.dsvFormat; dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; dsvDesc.Flags = 0; dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; @@ -2460,7 +2371,7 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, d3d11::SetDebugName(dsv, "TexStorageCube.RenderTargetDSV"); mRenderTarget[faceIndex][level] = new TextureRenderTarget11( - dsv, texture, srv, mInternalFormat, mTextureFormatSet->format, getLevelWidth(level), + dsv, texture, srv, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), getLevelHeight(level), 1, 0); // RenderTarget will take ownership of these resources @@ -2559,7 +2470,7 @@ gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture) desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; desc.ArraySize = CUBE_FACE_COUNT; - desc.Format = mSwizzleFormatSet->texFormat; + desc.Format = mFormatInfo.swizzle.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -2601,7 +2512,7 @@ gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.swizzle.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = 0; @@ -2623,6 +2534,66 @@ gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, return gl::Error(GL_NO_ERROR); } +gl::Error TextureStorage11::initDropStencilTexture(const gl::ImageIndexIterator &it) +{ + ID3D11Resource *resource = nullptr; + ANGLE_TRY(getResource(&resource)); + TextureHelper11 sourceTexture = TextureHelper11::MakeAndReference(resource, mFormatInfo); + TextureHelper11 destTexture = TextureHelper11::MakeAndReference( + mDropStencilTexture, + d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps())); + + gl::ImageIndexIterator itCopy = it; + + while (itCopy.hasNext()) + { + gl::ImageIndex index = itCopy.next(); + gl::Box wholeArea(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex), + 1); + gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1); + UINT subresource = getSubresourceIndex(index); + ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil(sourceTexture, subresource, wholeArea, + wholeSize, destTexture, subresource, + wholeArea, wholeSize, nullptr)); + } + + return gl::NoError(); +} + +gl::Error TextureStorage11_Cube::createDropStencilTexture() +{ + if (mDropStencilTexture) + { + return gl::NoError(); + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = 6; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + ID3D11Device *device = mRenderer->getDevice(); + + HRESULT hr = device->CreateTexture2D(&dropDesc, nullptr, &mDropStencilTexture); + if (FAILED(hr)) + { + return gl::Error(GL_INVALID_OPERATION, "Error creating drop stencil texture."); + } + d3d11::SetDebugName(mDropStencilTexture, "TexStorageCube.DropStencil"); + + ANGLE_TRY(initDropStencilTexture(gl::ImageIndexIterator::MakeCube(0, mMipLevels))); + + return gl::NoError(); +} + TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, @@ -2636,7 +2607,8 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, - levels)) + levels), + internalformat) { mTexture = nullptr; mSwizzleTexture = nullptr; @@ -2648,15 +2620,8 @@ TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, mSwizzleRenderTargets[i] = nullptr; } - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormatSet = formatInfo.formatSet; - mSwizzleFormatSet = formatInfo.swizzleFormatSet; - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &width, &height, &mTopLevel); + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); mMipLevels = mTopLevel + levels; mTextureWidth = width; @@ -2796,7 +2761,7 @@ gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource) desc.Height = mTextureHeight; desc.Depth = mTextureDepth; desc.MipLevels = mMipLevels; - desc.Format = mTextureFormatSet->texFormat; + desc.Format = mFormatInfo.texFormat; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = getBindFlags(); desc.CPUAccessFlags = 0; @@ -2859,37 +2824,25 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend const int mipLevel = index.mipIndex; ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - ASSERT(mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN); + ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); if (!index.hasLayer()) { if (!mLevelRenderTargets[mipLevel]) { ID3D11Resource *texture = nullptr; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getResource(&texture)); ID3D11ShaderResourceView *srv = nullptr; - error = getSRVLevel(mipLevel, false, &srv); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSRVLevel(mipLevel, false, &srv)); ID3D11ShaderResourceView *blitSRV = nullptr; - error = getSRVLevel(mipLevel, true, &blitSRV); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSRVLevel(mipLevel, true, &blitSRV)); ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = 0; @@ -2912,7 +2865,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend d3d11::SetDebugName(rtv, "TexStorage3D.RTV"); mLevelRenderTargets[mipLevel] = new TextureRenderTarget11( - rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + rtv, texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0); // RenderTarget will take ownership of these resources @@ -2945,7 +2898,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend ID3D11ShaderResourceView *blitSRV = nullptr; D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = layer; @@ -2969,7 +2922,7 @@ gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, Rend d3d11::SetDebugName(rtv, "TexStorage3D.LayerRTV"); mLevelLayerRenderTargets[key] = new TextureRenderTarget11( - rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + rtv, texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); // RenderTarget will take ownership of these resources @@ -2995,7 +2948,7 @@ gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture) desc.Height = mTextureHeight; desc.Depth = mTextureDepth; desc.MipLevels = mMipLevels; - desc.Format = mSwizzleFormatSet->texFormat; + desc.Format = mFormatInfo.swizzle.texFormat; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; @@ -3025,16 +2978,12 @@ gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11Render if (!mSwizzleRenderTargets[mipLevel]) { ID3D11Resource *swizzleTexture = nullptr; - gl::Error error = getSwizzleTexture(&swizzleTexture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSwizzleTexture(&swizzleTexture)); ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.swizzle.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = 0; @@ -3071,7 +3020,8 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, - levels)) + levels), + internalformat) { mTexture = nullptr; mSwizzleTexture = nullptr; @@ -3081,15 +3031,8 @@ TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, mSwizzleRenderTargets[level] = nullptr; } - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormatSet = formatInfo.formatSet; - mSwizzleFormatSet = formatInfo.swizzleFormatSet; - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormatSet->texFormat, &width, &height, &mTopLevel); + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); mMipLevels = mTopLevel + levels; mTextureWidth = width; @@ -3230,7 +3173,7 @@ gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource) desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; desc.ArraySize = mTextureDepth; - desc.Format = mTextureFormatSet->texFormat; + desc.Format = mFormatInfo.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -3335,22 +3278,14 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, HRESULT result; ID3D11Resource *texture = nullptr; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getResource(&texture)); ID3D11ShaderResourceView *srv; - error = createRenderTargetSRV(texture, index, mTextureFormatSet->srvFormat, &srv); - if (error.isError()) - { - return error; - } + ANGLE_TRY(createRenderTargetSRV(texture, index, mFormatInfo.srvFormat, &srv)); ID3D11ShaderResourceView *blitSRV; - if (mTextureFormatSet->blitSRVFormat != mTextureFormatSet->srvFormat) + if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) { - error = - createRenderTargetSRV(texture, index, mTextureFormatSet->blitSRVFormat, &blitSRV); + gl::Error error = + createRenderTargetSRV(texture, index, mFormatInfo.blitSRVFormat, &blitSRV); if (error.isError()) { SafeRelease(srv); @@ -3365,10 +3300,10 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, d3d11::SetDebugName(srv, "TexStorage2DArray.RenderTargetSRV"); - if (mTextureFormatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mTextureFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = layer; @@ -3391,7 +3326,7 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, d3d11::SetDebugName(rtv, "TexStorage2DArray.RenderTargetRTV"); mRenderTargets[key] = new TextureRenderTarget11( - rtv, texture, srv, blitSRV, mInternalFormat, mTextureFormatSet->format, + rtv, texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); // RenderTarget will take ownership of these resources @@ -3401,10 +3336,10 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, } else { - ASSERT(mTextureFormatSet->dsvFormat != DXGI_FORMAT_UNKNOWN); + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mTextureFormatSet->dsvFormat; + dsvDesc.Format = mFormatInfo.dsvFormat; dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; dsvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; dsvDesc.Texture2DArray.FirstArraySlice = layer; @@ -3426,7 +3361,7 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, d3d11::SetDebugName(dsv, "TexStorage2DArray.RenderTargetDSV"); mRenderTargets[key] = new TextureRenderTarget11( - dsv, texture, srv, mInternalFormat, mTextureFormatSet->format, + dsv, texture, srv, mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); // RenderTarget will take ownership of these resources @@ -3438,7 +3373,7 @@ gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, ASSERT(outRT); *outRT = mRenderTargets[key]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture) @@ -3452,7 +3387,7 @@ gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTextur desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; desc.ArraySize = mTextureDepth; - desc.Format = mSwizzleFormatSet->texFormat; + desc.Format = mFormatInfo.swizzle.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -3494,7 +3429,7 @@ gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11Device *device = mRenderer->getDevice(); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleFormatSet->rtvFormat; + rtvDesc.Format = mFormatInfo.swizzle.rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = 0; @@ -3515,4 +3450,42 @@ gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, *outRTV = mSwizzleRenderTargets[mipLevel]; return gl::Error(GL_NO_ERROR); } + +gl::Error TextureStorage11_2DArray::createDropStencilTexture() +{ + if (mDropStencilTexture) + { + return gl::NoError(); + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = mTextureDepth; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = 0; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + ID3D11Device *device = mRenderer->getDevice(); + + HRESULT hr = device->CreateTexture2D(&dropDesc, nullptr, &mDropStencilTexture); + if (FAILED(hr)) + { + return gl::Error(GL_INVALID_OPERATION, "Error creating drop stencil texture."); + } + d3d11::SetDebugName(mDropStencilTexture, "TexStorage2DArray.DropStencil"); + + std::vector<GLsizei> layerCounts(mMipLevels, mTextureDepth); + + ANGLE_TRY(initDropStencilTexture( + gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data()))); + + return gl::NoError(); +} + } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h index 222894dc3e6..46eb8458bef 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h @@ -59,8 +59,8 @@ class TextureStorage11 : public TextureStorage virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const; gl::Error generateSwizzles(const gl::SwizzleState &swizzleTarget); - void invalidateSwizzleCacheLevel(int mipLevel); - void invalidateSwizzleCache(); + void markLevelDirty(int mipLevel); + void markDirty(); gl::Error updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, const gl::ImageIndex &index, const gl::Box ©Area); @@ -79,10 +79,10 @@ class TextureStorage11 : public TextureStorage gl::Error getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV); - d3d11::ANGLEFormat getANGLEFormat() const; + const d3d11::Format &getFormatSet() const; protected: - TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags); + TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags, GLenum internalFormat); int getLevelWidth(int mipLevel) const; int getLevelHeight(int mipLevel) const; int getLevelDepth(int mipLevel) const; @@ -94,6 +94,10 @@ class TextureStorage11 : public TextureStorage virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0; gl::Error getSRVLevel(int mipLevel, bool blitSRV, ID3D11ShaderResourceView **outSRV); + // Get a version of a depth texture with only depth information, not stencil. + virtual gl::Error createDropStencilTexture(); + gl::Error initDropStencilTexture(const gl::ImageIndexIterator &it); + // The baseLevel parameter should *not* have mTopLevel applied. virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const = 0; @@ -107,14 +111,13 @@ class TextureStorage11 : public TextureStorage int mTopLevel; unsigned int mMipLevels; - GLenum mInternalFormat; - const d3d11::ANGLEFormatSet *mTextureFormatSet; - const d3d11::ANGLEFormatSet *mSwizzleFormatSet; + const d3d11::Format &mFormatInfo; unsigned int mTextureWidth; unsigned int mTextureHeight; unsigned int mTextureDepth; gl::SwizzleState mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + ID3D11Texture2D *mDropStencilTexture; private: const UINT mBindFlags; @@ -122,13 +125,14 @@ class TextureStorage11 : public TextureStorage struct SRVKey { - SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false); + SRVKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil); bool operator<(const SRVKey &rhs) const; - int baseLevel; // Without mTopLevel applied. - int mipLevels; - bool swizzle; + int baseLevel = 0; // Without mTopLevel applied. + int mipLevels = 0; + bool swizzle = false; + bool dropStencil = false; }; typedef std::map<SRVKey, ID3D11ShaderResourceView *> SRVCache; @@ -144,30 +148,35 @@ class TextureStorage11_2D : public TextureStorage11 public: TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain); TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly = false); - virtual ~TextureStorage11_2D(); + ~TextureStorage11_2D() override; - virtual gl::Error getResource(ID3D11Resource **outResource); - virtual gl::Error getMippedResource(ID3D11Resource **outResource); - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error getResource(ID3D11Resource **outResource) override; + gl::Error getMippedResource(ID3D11Resource **outResource) override; + gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override; - virtual gl::Error copyToStorage(TextureStorage *destStorage); + gl::Error copyToStorage(TextureStorage *destStorage) override; - virtual void associateImage(Image11* image, const gl::ImageIndex &index); - virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); - virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); - virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + bool isAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11 *incomingImage) override; - virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture); + gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) override; protected: - virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); - virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); + gl::Error getSwizzleTexture(ID3D11Resource **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) override; + + gl::Error createDropStencilTexture() override; gl::Error ensureTextureExists(int mipLevels); private: - virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const; + gl::Error createSRV(int baseLevel, + int mipLevels, + DXGI_FORMAT format, + ID3D11Resource *texture, + ID3D11ShaderResourceView **outSRV) const override; ID3D11Texture2D *mTexture; RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; @@ -233,7 +242,9 @@ class TextureStorage11_External : public TextureStorage11 class TextureStorage11_EGLImage final : public TextureStorage11 { public: - TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage); + TextureStorage11_EGLImage(Renderer11 *renderer, + EGLImageD3D *eglImage, + RenderTarget11 *renderTarget11); ~TextureStorage11_EGLImage() override; gl::Error getResource(ID3D11Resource **outResource) override; @@ -301,6 +312,8 @@ class TextureStorage11_Cube : public TextureStorage11 virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); + gl::Error createDropStencilTexture() override; + gl::Error ensureTextureExists(int mipLevels); private: @@ -384,6 +397,8 @@ class TextureStorage11_2DArray : public TextureStorage11 virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); + gl::Error createDropStencilTexture() override; + private: virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, ID3D11ShaderResourceView **outSRV) const; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp new file mode 100644 index 00000000000..39b293f9b09 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp @@ -0,0 +1,102 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers. + +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state, + Renderer11 *renderer) + : TransformFeedbackImpl(state), + mRenderer(renderer), + mIsDirty(true), + mBuffers(state.getIndexedBuffers().size(), nullptr), + mBufferOffsets(state.getIndexedBuffers().size(), 0) +{ +} + +TransformFeedback11::~TransformFeedback11() +{ +} + +void TransformFeedback11::begin(GLenum primitiveMode) +{ +} + +void TransformFeedback11::end() +{ + if (mRenderer->getWorkarounds().flushAfterEndingTransformFeedback) + { + mRenderer->getDeviceContext()->Flush(); + } +} + +void TransformFeedback11::pause() +{ +} + +void TransformFeedback11::resume() +{ +} + +void TransformFeedback11::bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) +{ +} + +void TransformFeedback11::bindIndexedBuffer(size_t index, + const OffsetBindingPointer<gl::Buffer> &binding) +{ + mIsDirty = true; + mBufferOffsets[index] = static_cast<UINT>(binding.getOffset()); +} + +void TransformFeedback11::onApply() +{ + mIsDirty = false; + + // Change all buffer offsets to -1 so that if any of them need to be re-applied, the are set to + // append + std::fill(mBufferOffsets.begin(), mBufferOffsets.end(), -1); +} + +bool TransformFeedback11::isDirty() const +{ + return mIsDirty; +} + +UINT TransformFeedback11::getNumSOBuffers() const +{ + return static_cast<UINT>(mBuffers.size()); +} + +gl::ErrorOrResult<const std::vector<ID3D11Buffer *> *> TransformFeedback11::getSOBuffers() +{ + for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) + { + const auto &binding = mState.getIndexedBuffer(bindingIdx); + if (binding.get() != nullptr) + { + Buffer11 *storage = GetImplAs<Buffer11>(binding.get()); + ANGLE_TRY_RESULT(storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), + mBuffers[bindingIdx]); + } + } + + return &mBuffers; +} + +const std::vector<UINT> &TransformFeedback11::getSOBufferOffsets() const +{ + return mBufferOffsets; +} +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h new file mode 100644 index 00000000000..01879d6f3af --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h @@ -0,0 +1,54 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedback11.h: Implements the abstract rx::TransformFeedbackImpl class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ + +#include "common/platform.h" + +#include "libANGLE/angletypes.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/TransformFeedbackImpl.h" + +namespace rx +{ + +class Renderer11; + +class TransformFeedback11 : public TransformFeedbackImpl +{ + public: + TransformFeedback11(const gl::TransformFeedbackState &state, Renderer11 *renderer); + ~TransformFeedback11() override; + + void begin(GLenum primitiveMode) override; + void end() override; + void pause() override; + void resume() override; + + void bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) override; + void bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding) override; + + void onApply(); + + bool isDirty() const; + + UINT getNumSOBuffers() const; + gl::ErrorOrResult<const std::vector<ID3D11Buffer *> *> getSOBuffers(); + const std::vector<UINT> &getSOBufferOffsets() const; + + private: + Renderer11 *mRenderer; + + bool mIsDirty; + std::vector<ID3D11Buffer *> mBuffers; + std::vector<UINT> mBufferOffsets; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp index ca48b1872c4..29185a9d934 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp @@ -47,7 +47,6 @@ void Trim11::trim() #if defined (ANGLE_ENABLE_WINDOWS_STORE) ID3D11Device* device = mRenderer->getDevice(); - // IDXGIDevice3 is only supported on Windows 8.1 and Windows Phone 8.1 and above. IDXGIDevice3 *dxgiDevice3 = d3d11::DynamicCastComObject<IDXGIDevice3>(device); if (dxgiDevice3) { diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp index 8a0153c988d..7895bf18f47 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp @@ -9,13 +9,14 @@ #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/formatutils.h" -#include "libANGLE/renderer/copyimage.h" #include "libANGLE/renderer/d3d/d3d11/copyvertex.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/generatemip.h" -#include "libANGLE/renderer/d3d/loadimage.h" namespace rx { @@ -23,204 +24,9 @@ namespace rx namespace d3d11 { -struct D3D11FastCopyFormat -{ - GLenum destFormat; - GLenum destType; - ColorCopyFunction copyFunction; - - D3D11FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) - : destFormat(destFormat), destType(destType), copyFunction(copyFunction) - { } - - bool operator<(const D3D11FastCopyFormat& other) const - { - return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0; - } -}; - -static const FastCopyFunctionMap &GetFastCopyFunctionMap(DXGI_FORMAT dxgiFormat) -{ - switch (dxgiFormat) - { - case DXGI_FORMAT_B8G8R8A8_UNORM: - { - static FastCopyFunctionMap fastCopyMap; - if (fastCopyMap.empty()) - { - fastCopyMap[gl::FormatType(GL_RGBA, GL_UNSIGNED_BYTE)] = CopyBGRA8ToRGBA8; - } - return fastCopyMap; - } - default: - { - static FastCopyFunctionMap emptyMap; - return emptyMap; - } - } -} - -struct DXGIColorFormatInfo -{ - size_t redBits; - size_t greenBits; - size_t blueBits; - - size_t luminanceBits; - - size_t alphaBits; - size_t sharedBits; -}; - -typedef std::map<DXGI_FORMAT, DXGIColorFormatInfo> ColorFormatInfoMap; -typedef std::pair<DXGI_FORMAT, DXGIColorFormatInfo> ColorFormatInfoPair; - -static inline void InsertDXGIColorFormatInfo(ColorFormatInfoMap *map, DXGI_FORMAT format, size_t redBits, size_t greenBits, - size_t blueBits, size_t alphaBits, size_t sharedBits) -{ - DXGIColorFormatInfo info; - info.redBits = redBits; - info.greenBits = greenBits; - info.blueBits = blueBits; - info.alphaBits = alphaBits; - info.sharedBits = sharedBits; - - map->insert(std::make_pair(format, info)); -} - -static ColorFormatInfoMap BuildColorFormatInfoMap() -{ - ColorFormatInfoMap map; - - // clang-format off - // | DXGI format | R | G | B | A | S | - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_A8_UNORM, 0, 0, 0, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UNORM, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_UNORM, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_UNORM, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_UNORM, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_UNORM, 16, 16, 16, 16, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_SNORM, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_SNORM, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_SNORM, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_SNORM, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_SNORM, 16, 16, 16, 16, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UINT, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_UINT, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_UINT, 32, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_UINT, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_UINT, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_UINT, 32, 32, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_UINT, 32, 32, 32, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UINT, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_UINT, 16, 16, 16, 16, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_UINT, 32, 32, 32, 32, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_SINT, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_SINT, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_SINT, 32, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_SINT, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_SINT, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_SINT, 32, 32, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_SINT, 32, 32, 32, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_SINT, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_SINT, 16, 16, 16, 16, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_SINT, 32, 32, 32, 32, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_TYPELESS, 10, 10, 10, 2, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UINT, 10, 10, 10, 2, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_FLOAT, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_FLOAT, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 16, 16, 16, 16, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_FLOAT, 32, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_FLOAT, 32, 32, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_FLOAT, 32, 32, 32, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 32, 32, 32, 32, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, 9, 9, 0, 5); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R11G11B10_FLOAT, 11, 11, 10, 0, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G6R5_UNORM, 5, 6, 5, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B4G4R4A4_UNORM, 4, 4, 4, 4, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G5R5A1_UNORM, 5, 5, 5, 1, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_TYPELESS, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_TYPELESS, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_TYPELESS, 32, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_TYPELESS, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_TYPELESS, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_TYPELESS, 32, 32, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_TYPELESS, 32, 32, 32, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_TYPELESS, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_TYPELESS, 16, 16, 16, 16, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_TYPELESS, 32, 32, 32, 32, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R24G8_TYPELESS, 24, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 24, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 32, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 32, 0, 0, 0, 0); - // clang-format on - - return map; -} - -struct DXGIDepthStencilInfo -{ - unsigned int depthBits; - unsigned int stencilBits; -}; - -typedef std::map<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoMap; -typedef std::pair<DXGI_FORMAT, DXGIDepthStencilInfo> DepthStencilInfoPair; - -static inline void InsertDXGIDepthStencilInfo(DepthStencilInfoMap *map, - DXGI_FORMAT format, - unsigned int depthBits, - unsigned int stencilBits) -{ - DXGIDepthStencilInfo info; - info.depthBits = depthBits; - info.stencilBits = stencilBits; - - map->insert(std::make_pair(format, info)); -} - -static DepthStencilInfoMap BuildDepthStencilInfoMap() -{ - DepthStencilInfoMap map; - - // clang-format off - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D16_UNORM, 16, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 24, 8); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT, 32, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, 8); - // clang-format on - - return map; -} - typedef std::map<DXGI_FORMAT, DXGIFormat> DXGIFormatInfoMap; -DXGIFormat::DXGIFormat() - : redBits(0), - greenBits(0), - blueBits(0), - alphaBits(0), - sharedBits(0), - depthBits(0), - stencilBits(0), - componentType(GL_NONE), - fastCopyFunctions(), - nativeMipmapSupport(NULL) +DXGIFormat::DXGIFormat() : componentType(GL_NONE), nativeMipmapSupport(NULL) { } @@ -242,29 +48,7 @@ void AddDXGIFormat(DXGIFormatInfoMap *map, { DXGIFormat info; - static const ColorFormatInfoMap colorInfoMap = BuildColorFormatInfoMap(); - ColorFormatInfoMap::const_iterator colorInfoIter = colorInfoMap.find(dxgiFormat); - if (colorInfoIter != colorInfoMap.end()) - { - const DXGIColorFormatInfo &colorInfo = colorInfoIter->second; - info.redBits = static_cast<GLuint>(colorInfo.redBits); - info.greenBits = static_cast<GLuint>(colorInfo.greenBits); - info.blueBits = static_cast<GLuint>(colorInfo.blueBits); - info.alphaBits = static_cast<GLuint>(colorInfo.alphaBits); - info.sharedBits = static_cast<GLuint>(colorInfo.sharedBits); - } - - static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap(); - DepthStencilInfoMap::const_iterator dsInfoIter = dsInfoMap.find(dxgiFormat); - if (dsInfoIter != dsInfoMap.end()) - { - const DXGIDepthStencilInfo &dsInfo = dsInfoIter->second; - info.depthBits = dsInfo.depthBits; - info.stencilBits = dsInfo.stencilBits; - } - info.componentType = componentType; - info.fastCopyFunctions = GetFastCopyFunctionMap(dxgiFormat); info.nativeMipmapSupport = nativeMipmapSupport; map->insert(std::make_pair(dxgiFormat, info)); @@ -1189,6 +973,6 @@ const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D } } -} +} // namespace d3d11 -} +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h index 8d719d37418..14bde45e487 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h @@ -31,19 +31,8 @@ struct DXGIFormat { DXGIFormat(); - GLuint redBits; - GLuint greenBits; - GLuint blueBits; - GLuint alphaBits; - GLuint sharedBits; - - GLuint depthBits; - GLuint stencilBits; - GLenum componentType; - FastCopyFunctionMap fastCopyFunctions; - NativeMipmapGenerationSupportFunction nativeMipmapSupport; }; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.py b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.py deleted file mode 100644 index 33240cedd87..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/python -# Copyright 2015 The ANGLE Project Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# gen_load_functions_table.py: -# Code generation for the load function tables used for texture formats -# - -import json - -template = """// GENERATED FILE - DO NOT EDIT. -// Generated by gen_load_functions_table.py using data from load_functions_data.json -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// load_functions_table: -// Contains the GetLoadFunctionsMap for texture_format_util.h -// - -#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" -#include "libANGLE/renderer/d3d/loadimage.h" -#include "libANGLE/renderer/d3d/loadimage_etc.h" - -namespace rx -{{ - -namespace d3d11 -{{ - -namespace -{{ - -// ES3 image loading functions vary based on: -// - the GL internal format (supplied to glTex*Image*D) -// - the GL data type given (supplied to glTex*Image*D) -// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D -// device's capabilities) -// This map type determines which loading function to use, based on these three parameters. -// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. -void UnimplementedLoadFunction(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{{ - UNIMPLEMENTED(); -}} - -void UnreachableLoadFunction(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{{ - UNREACHABLE(); -}} - -}} // namespace - -// TODO we can replace these maps with more generated code -const std::map<GLenum, LoadImageFunctionInfo> &GetLoadFunctionsMap(GLenum {internal_format}, - DXGI_FORMAT {dxgi_format}) -{{ - // clang-format off - switch ({internal_format}) - {{ -{data} - default: - {{ - static std::map<GLenum, LoadImageFunctionInfo> emptyLoadFunctionsMap; - return emptyLoadFunctionsMap; - }} - }} - // clang-format on - -}} // GetLoadFunctionsMap - -}} // namespace d3d11 - -}} // namespace rx -""" - -internal_format_param = 'internalFormat' -dxgi_format_param = 'dxgiFormat' -dxgi_format_unknown = "DXGI_FORMAT_UNKNOWN" - -def get_function_maps_string(typestr, function, requiresConversion): - return ' { ' + typestr + ', LoadImageFunctionInfo(' + function + ', ' + requiresConversion + ') },\n' - -def get_unknown_format_string(dxgi_to_type_map, dxgi_unknown_string): - if dxgi_unknown_string not in dxgi_to_type_map: - return '' - - table_data = '' - - for unknown_type_function in dxgi_to_type_map[dxgi_unknown_string]: - table_data += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction'], 'true') - - return table_data - -# Making map from dxgi to type map for a particular internalFormat -def create_dxgi_to_type_map(dst, json_data, internal_format_str): - for type_item in sorted(json_data[internal_format_str].iteritems()): - for entry_in_type_item in type_item[1]: - dxgi_format_str = entry_in_type_item['dxgiFormat'] - - if dxgi_format_str not in dst: - dst[dxgi_format_str] = [] - - type_dxgi_load_function = entry_in_type_item.copy(); - type_dxgi_load_function['type'] = type_item[0] - dst[dxgi_format_str].append(type_dxgi_load_function) - -def get_load_function_map_snippet(insert_map_string): - load_function_map_snippet = '' - load_function_map_snippet += ' static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = {\n' - load_function_map_snippet += insert_map_string - load_function_map_snippet += ' };\n\n' - load_function_map_snippet += ' return loadFunctionsMap;\n' - - return load_function_map_snippet - -def parse_json_into_switch_string(json_data): - table_data = '' - for internal_format_item in sorted(json_data.iteritems()): - internal_format_str = internal_format_item[0] - table_data += ' case ' + internal_format_str + ':\n' - table_data += ' {\n' - table_data += ' switch (' + dxgi_format_param + ')\n' - table_data += ' {\n' - - dxgi_to_type_map = {}; - create_dxgi_to_type_map(dxgi_to_type_map, json_data, internal_format_str) - - dxgi_unknown_str = get_unknown_format_string(dxgi_to_type_map, dxgi_format_unknown); - - for dxgi_format_item in sorted(dxgi_to_type_map.iteritems()): - dxgi_format_str = dxgi_format_item[0] - - # Main case statements - table_data += ' case ' + dxgi_format_str + ':\n' - table_data += ' {\n' - insert_map_string = '' - types_already_in_loadmap = set() - for type_function in sorted(dxgi_format_item[1]): - insert_map_string += get_function_maps_string(type_function['type'], type_function['loadFunction'], type_function['requiresConversion']) - types_already_in_loadmap.add(type_function['type']) - - # DXGI_FORMAT_UNKNOWN add ons - if dxgi_format_unknown in dxgi_to_type_map: - for unknown_type_function in dxgi_to_type_map[dxgi_format_unknown]: - # Check that it's not already in the loadmap so it doesn't override the value - if unknown_type_function['type'] not in types_already_in_loadmap: - insert_map_string += get_function_maps_string(unknown_type_function['type'], unknown_type_function['loadFunction'], 'true') - - table_data += get_load_function_map_snippet(insert_map_string) - table_data += ' }\n' - - table_data += ' default:\n' - - if dxgi_unknown_str: - table_data += ' {\n' - table_data += get_load_function_map_snippet(dxgi_unknown_str) - table_data += ' }\n' - else: - table_data += ' break;\n' - table_data += ' }\n' - table_data += ' }\n' - - return table_data - -with open('load_functions_data.json') as functions_json_file: - functions_data = functions_json_file.read(); - functions_json_file.close() - json_data = json.loads(functions_data) - - table_data = parse_json_into_switch_string(json_data) - output = template.format(internal_format = internal_format_param, - dxgi_format = dxgi_format_param, - data=table_data) - - with open('load_functions_table_autogen.cpp', 'wt') as out_file: - out_file.write(output) - out_file.close() diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py index b28a9ea8ac5..981a77f51ab 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py @@ -11,31 +11,12 @@ from datetime import date import json import math import pprint +import os import re +import sys -template_texture_format_table_autogen_h = """// GENERATED FILE - DO NOT EDIT. -// Generated by gen_texture_format_table.py using data from texture_format_data.json -// -// Copyright 2016 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -namespace rx -{{ - -namespace d3d11 -{{ - -enum ANGLEFormat -{{ -{angle_format_enum} -}}; - -}} // namespace d3d11 - -}} // namespace rx -""" +sys.path.append('../..') +import angle_format template_texture_format_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. // Generated by gen_texture_format_table.py using data from texture_format_data.json @@ -50,12 +31,15 @@ template_texture_format_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" -#include "libANGLE/renderer/copyimage.h" +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "libANGLE/renderer/d3d/generatemip.h" -#include "libANGLE/renderer/d3d/loadimage.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h" + +using namespace angle; namespace rx {{ @@ -63,140 +47,11 @@ namespace rx namespace d3d11 {{ -namespace -{{ - -typedef bool (*FormatSupportFunction)(const Renderer11DeviceCaps &); - -bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) -{{ - return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); -}} - -bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) -{{ - return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); -}} - -template <DXGI_FORMAT format, bool requireSupport> -bool SupportsFormat(const Renderer11DeviceCaps &deviceCaps) -{{ - // Must support texture, SRV and RTV support - UINT mustSupport = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | - D3D11_FORMAT_SUPPORT_RENDER_TARGET; - - if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel) > 2) - {{ - mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; - }} - - bool fullSupport = false; - if (format == DXGI_FORMAT_B5G6R5_UNORM) - {{ - // All hardware that supports DXGI_FORMAT_B5G6R5_UNORM should support autogen mipmaps, but - // check anyway. - mustSupport |= D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; - fullSupport = ((deviceCaps.B5G6R5support & mustSupport) == mustSupport); - }} - else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) - {{ - fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport); - }} - else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) - {{ - fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport); - }} - else - {{ - UNREACHABLE(); - return false; - }} - - // This 'SupportsFormat' function is used by individual entries in the D3D11 Format Map below, - // which maps GL formats to DXGI formats. - if (requireSupport) - {{ - // This means that ANGLE would like to use the entry in the map if the inputted DXGI format - // *IS* supported. - // e.g. the entry might map GL_RGB5_A1 to DXGI_FORMAT_B5G5R5A1, which should only be used if - // DXGI_FORMAT_B5G5R5A1 is supported. - // In this case, we should only return 'true' if the format *IS* supported. - return fullSupport; - }} - else - {{ - // This means that ANGLE would like to use the entry in the map if the inputted DXGI format - // *ISN'T* supported. - // This might be a fallback entry. e.g. for ANGLE to use DXGI_FORMAT_R8G8B8A8_UNORM if - // DXGI_FORMAT_B5G5R5A1 isn't supported. - // In this case, we should only return 'true' if the format *ISN'T* supported. - return !fullSupport; - }} -}} - -// End Format Support Functions -}} // namespace - -ANGLEFormatSet::ANGLEFormatSet() - : format(ANGLE_FORMAT_NONE), - glInternalFormat(GL_NONE), - texFormat(DXGI_FORMAT_UNKNOWN), - srvFormat(DXGI_FORMAT_UNKNOWN), - rtvFormat(DXGI_FORMAT_UNKNOWN), - dsvFormat(DXGI_FORMAT_UNKNOWN), - blitSRVFormat(DXGI_FORMAT_UNKNOWN), - swizzleFormat(ANGLE_FORMAT_NONE), - mipGenerationFunction(nullptr), - colorReadFunction(nullptr) -{{ -}} - -// For sized GL internal formats, there are several possible corresponding D3D11 formats depending -// on device capabilities. -// This function allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and -// DSVs given a GL internal format. -TextureFormat::TextureFormat(GLenum internalFormat, - const ANGLEFormat angleFormat, - InitializeTextureDataFunction internalFormatInitializer) - : dataInitializerFunction(internalFormatInitializer) -{{ - formatSet = &GetANGLEFormatSet(angleFormat); - swizzleFormatSet = &GetANGLEFormatSet(formatSet->swizzleFormat); - - // Gather all the load functions for this internal format - loadFunctions = GetLoadFunctionsMap(internalFormat, formatSet->texFormat); - - ASSERT(loadFunctions.size() != 0 || internalFormat == GL_NONE); -}} - -ANGLEFormatSet::ANGLEFormatSet(ANGLEFormat format, - GLenum glInternalFormat, - DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, - DXGI_FORMAT rtvFormat, - DXGI_FORMAT dsvFormat, - DXGI_FORMAT blitSRVFormat, - ANGLEFormat swizzleFormat, - MipGenerationFunction mipGenerationFunction, - ColorReadFunction colorReadFunction) - : format(format), - glInternalFormat(glInternalFormat), - texFormat(texFormat), - srvFormat(srvFormat), - rtvFormat(rtvFormat), - dsvFormat(dsvFormat), - blitSRVFormat(blitSRVFormat), - swizzleFormat(swizzleFormat), - mipGenerationFunction(mipGenerationFunction), - colorReadFunction(colorReadFunction) -{{ -}} - -const ANGLEFormatSet &GetANGLEFormatSet(ANGLEFormat angleFormat) +// static +const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps) {{ // clang-format off - switch (angleFormat) + switch (internalFormat) {{ {angle_format_info_cases} default: @@ -205,26 +60,10 @@ const ANGLEFormatSet &GetANGLEFormatSet(ANGLEFormat angleFormat) // clang-format on UNREACHABLE(); - static const ANGLEFormatSet defaultInfo; + static const Format defaultInfo; return defaultInfo; }} -const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, - const Renderer11DeviceCaps &renderer11DeviceCaps) -{{ - // clang-format off - switch (internalFormat) - {{ -{texture_format_info_cases} - default: - break; - }} - // clang-format on - - static const TextureFormat defaultInfo(GL_NONE, ANGLE_FORMAT_NONE, nullptr); - return defaultInfo; -}} // GetTextureFormatInfo - }} // namespace d3d11 }} // namespace rx @@ -305,16 +144,18 @@ def get_internal_format_initializer(internal_format, angle_format): return internal_format_initializer -def get_swizzle_format_id(angle_format_id, angle_format): - if angle_format_id == 'ANGLE_FORMAT_NONE': - return 'ANGLE_FORMAT_NONE' +def get_swizzle_format_id(internal_format, angle_format): + angle_format_id = angle_format["formatName"] + if (internal_format == 'GL_NONE') or (angle_format_id == 'NONE'): + return 'GL_NONE' + elif 'swizzleFormat' in angle_format: # For some special formats like compressed formats that don't have a clearly defined number # of bits per channel, swizzle format needs to be specified manually. return angle_format['swizzleFormat'] if 'bits' not in angle_format: - raise ValueError('no bits information for determining swizzleformat for format: ' + angle_format_id) + raise ValueError('no bits information for determining swizzleformat for format: ' + internal_format) bits = angle_format['bits'] max_component_bits = max(bits.itervalues()) @@ -323,7 +164,7 @@ def get_swizzle_format_id(angle_format_id, angle_format): # The format itself can be used for swizzles if it can be accessed as a render target and # sampled and the bit count for all 4 channels is the same. if "rtvFormat" in angle_format and "srvFormat" in angle_format and not channels_different and len(angle_format['channels']) == 4: - return angle_format_id + return angle_format["glInternalFormat"] if "glInternalFormat" in angle_format else internal_format b = int(math.ceil(float(max_component_bits) / 8) * 8) @@ -331,170 +172,167 @@ def get_swizzle_format_id(angle_format_id, angle_format): # defined component type. if angle_format['channels'].find('d') >= 0: if b == 24 or b == 32: - return 'ANGLE_FORMAT_R32G32B32A32_FLOAT' + return 'GL_RGBA32F' if b == 16: - return 'ANGLE_FORMAT_R16G16B16A16_UNORM' + return 'GL_RGBA16_EXT' if b == 24: - raise ValueError('unexpected 24-bit format when determining swizzleformat for format: ' + angle_format_id) + raise ValueError('unexpected 24-bit format when determining swizzleformat for format: ' + internal_format) if 'componentType' not in angle_format: - raise ValueError('no component type information for determining swizzleformat for format: ' + angle_format_id) + raise ValueError('no component type information for determining swizzleformat for format: ' + internal_format) component_type = angle_format['componentType'] + + swizzle = "GL_RGBA" + str(b) + if component_type == 'uint': - return 'ANGLE_FORMAT_R{}G{}B{}A{}_UINT'.format(b, b, b, b) + swizzle += "I" elif component_type == 'int': - return 'ANGLE_FORMAT_R{}G{}B{}A{}_SINT'.format(b, b, b, b) + swizzle += "I" elif component_type == 'unorm': - return 'ANGLE_FORMAT_R{}G{}B{}A{}_UNORM'.format(b, b, b, b) + if (b == 16): + swizzle += "_EXT" elif component_type == 'snorm': - return 'ANGLE_FORMAT_R{}G{}B{}A{}_SNORM'.format(b, b, b, b) + swizzle += "_SNORM" + if (b == 16): + swizzle += "_EXT" elif component_type == 'float': - return 'ANGLE_FORMAT_R{}G{}B{}A{}_FLOAT'.format(b, b, b, b) + swizzle += "F" + if (b == 16): + swizzle += "_EXT" else: - raise ValueError('could not determine swizzleformat based on componentType for format: ' + angle_format_id) + raise ValueError('could not determine swizzleformat based on componentType for format: ' + internal_format) -def get_texture_format_item(idx, internal_format, requirements_fn, angle_format_id, angle_format): - table_data = ''; + return swizzle - internal_format_initializer = get_internal_format_initializer(internal_format, angle_format) +def get_blit_srv_format(angle_format): + if 'channels' not in angle_format: + return 'DXGI_FORMAT_UNKNOWN' + if 'r' in angle_format['channels'] and angle_format['componentType'] in ['int', 'uint']: + return angle_format['rtvFormat'] - indent = ' ' - if requirements_fn != None: - if idx == 0: - table_data += ' if (' + requirements_fn + '(renderer11DeviceCaps))\n' - else: - table_data += ' else if (' + requirements_fn + '(renderer11DeviceCaps))\n' - table_data += ' {\n' - indent += ' ' + return angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" - table_data += indent + 'static const TextureFormat textureFormat(internalFormat,\n' - table_data += indent + ' ' + angle_format_id + ',\n' - table_data += indent + ' ' + internal_format_initializer + ');\n' - table_data += indent + 'return textureFormat;\n' - if requirements_fn != None: - table_data += ' }\n' +format_entry_template = """{space}{{ +{space} static const Format info({internalFormat}, +{space} angle::Format::ID::{formatName}, +{space} {texFormat}, +{space} {srvFormat}, +{space} {rtvFormat}, +{space} {dsvFormat}, +{space} {blitSRVFormat}, +{space} {swizzleFormat}, +{space} {initializer}, +{space} deviceCaps); +{space} return info; +{space}}} +""" - return table_data +split_format_entry_template = """{space} {condition} +{space} {{ +{space} static const Format info({internalFormat}, +{space} angle::Format::ID::{formatName}, +{space} {texFormat}, +{space} {srvFormat}, +{space} {rtvFormat}, +{space} {dsvFormat}, +{space} {blitSRVFormat}, +{space} {swizzleFormat}, +{space} {initializer}, +{space} deviceCaps); +{space} return info; +{space} }} +""" -def parse_json_into_switch_texture_format_string(json_map, json_data): - table_data = '' - angle_format_map = {} +def json_to_table_data(internal_format, format_name, prefix, json): - for internal_format_item in sorted(json_map.iteritems()): - internal_format = internal_format_item[0] - table_data += ' case ' + internal_format + ':\n' - table_data += ' {\n' + table_data = "" - if isinstance(json_map[internal_format], basestring): - angle_format_id = json_map[internal_format] - table_data += get_texture_format_item(0, internal_format, None, angle_format_id, json_data[angle_format_id]) - else: - for idx, requirements_map in enumerate(sorted(json_map[internal_format].iteritems())): - angle_format_id = requirements_map[1] - table_data += get_texture_format_item(idx, internal_format, requirements_map[0], angle_format_id, json_data[angle_format_id]) - table_data += ' else\n' - table_data += ' {\n' - table_data += ' break;\n' - table_data += ' }\n' + parsed = { + "space": " ", + "internalFormat": internal_format, + "formatName": format_name, + "texFormat": "DXGI_FORMAT_UNKNOWN", + "srvFormat": "DXGI_FORMAT_UNKNOWN", + "rtvFormat": "DXGI_FORMAT_UNKNOWN", + "dsvFormat": "DXGI_FORMAT_UNKNOWN", + "condition": prefix, + } - table_data += ' }\n' + for k, v in json.iteritems(): + parsed[k] = v - return table_data + # Derived values. + parsed["blitSRVFormat"] = get_blit_srv_format(parsed) + parsed["swizzleFormat"] = get_swizzle_format_id(internal_format, parsed) + parsed["initializer"] = get_internal_format_initializer(internal_format, json) -def get_channel_struct(angle_format): - if 'bits' not in angle_format: - return None - bits = angle_format['bits'] - if 'depth' in bits or 'stencil' in bits: - return None - - if 'channelStruct' in angle_format: - return angle_format['channelStruct'] - - struct_name = '' - for channel in angle_format['channels']: - if channel == 'r': - struct_name += 'R{}'.format(bits['red']) - if channel == 'g': - struct_name += 'G{}'.format(bits['green']) - if channel == 'b': - struct_name += 'B{}'.format(bits['blue']) - if channel == 'a': - struct_name += 'A{}'.format(bits['alpha']) - if angle_format['componentType'] == 'float': - struct_name += 'F' - if angle_format['componentType'] == 'int' or angle_format['componentType'] == 'snorm': - struct_name += 'S' - return struct_name - -def get_mip_generation_function(angle_format): - channel_struct = get_channel_struct(angle_format) - if channel_struct == None: - return 'nullptr' - return 'GenerateMip<' + channel_struct + '>' - -def get_color_read_function(angle_format): - channel_struct = get_channel_struct(angle_format) - if channel_struct == None: - return 'nullptr' - component_type_map = { - 'uint': 'GLuint', - 'int': 'GLint', - 'unorm': 'GLfloat', - 'snorm': 'GLfloat', - 'float': 'GLfloat' - } - return 'ReadColor<' + channel_struct + ', '+ component_type_map[angle_format['componentType']] + '>' + if len(prefix) > 0: + return split_format_entry_template.format(**parsed) + else: + return format_entry_template.format(**parsed) + +def parse_json_angle_format_case(format_name, angle_format, json_data): + supported_case = {} + unsupported_case = {} + support_test = None + fallback = None + + for k, v in angle_format.iteritems(): + if k == "FL10Plus": + assert support_test is None + support_test = "OnlyFL10Plus(deviceCaps)" + for k2, v2 in v.iteritems(): + supported_case[k2] = v2 + elif k == "FL9_3": + split = True + for k2, v2 in v.iteritems(): + unsupported_case[k2] = v2 + elif k == "supportTest": + assert support_test is None + support_test = v + elif k == "fallbackFormat": + fallback = v + else: + supported_case[k] = v + unsupported_case[k] = v -def get_blit_srv_format(angle_format): - if 'channels' not in angle_format: - return 'DXGI_FORMAT_UNKNOWN' - if 'r' in angle_format['channels'] and angle_format['componentType'] in ['int', 'uint']: - return angle_format['rtvFormat'] + if fallback != None: + unsupported_case, _, _ = parse_json_angle_format_case( + fallback, json_data[fallback], json_data) + unsupported_case["formatName"] = fallback - return angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" + if support_test != None: + return supported_case, unsupported_case, support_test + else: + return supported_case, None, None -def parse_json_into_switch_angle_format_string(json_data): +def parse_json_into_switch_angle_format_string(json_map, json_data): table_data = '' - for angle_format_item in sorted(json_data.iteritems()): - table_data += ' case ' + angle_format_item[0] + ':\n' - angle_format = angle_format_item[1] - gl_internal_format = angle_format["glInternalFormat"] if "glInternalFormat" in angle_format else "GL_NONE" - tex_format = angle_format["texFormat"] if "texFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" - srv_format = angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" - rtv_format = angle_format["rtvFormat"] if "rtvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" - dsv_format = angle_format["dsvFormat"] if "dsvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" - blit_srv_format = get_blit_srv_format(angle_format) - swizzle_format = get_swizzle_format_id(angle_format_item[0], angle_format) - mip_generation_function = get_mip_generation_function(angle_format) - color_read_function = get_color_read_function(angle_format) - table_data += ' {\n' - table_data += ' static const ANGLEFormatSet formatInfo(' + angle_format_item[0] + ',\n' - table_data += ' ' + gl_internal_format + ',\n' - table_data += ' ' + tex_format + ',\n' - table_data += ' ' + srv_format + ',\n' - table_data += ' ' + rtv_format + ',\n' - table_data += ' ' + dsv_format + ',\n' - table_data += ' ' + blit_srv_format + ',\n' - table_data += ' ' + swizzle_format + ',\n' - table_data += ' ' + mip_generation_function + ',\n' - table_data += ' ' + color_read_function + ');\n' - table_data += ' return formatInfo;\n' - table_data += ' }\n' - return table_data -def parse_json_into_angle_format_enum_string(json_data): - enum_data = '' - index = 0 - for angle_format_item in sorted(json_data.iteritems()): - if index > 0: - enum_data += ',\n' - enum_data += ' ' + angle_format_item[0] - index += 1 - return enum_data + for internal_format, format_name in sorted(json_map.iteritems()): + + if format_name not in json_data: + continue + + angle_format = json_data[format_name] + + supported_case, unsupported_case, support_test = parse_json_angle_format_case( + format_name, angle_format, json_data) + + table_data += ' case ' + internal_format + ':\n' + + if support_test != None: + table_data += " {\n" + table_data += json_to_table_data(internal_format, format_name, "if (" + support_test + ")", supported_case) + table_data += json_to_table_data(internal_format, format_name, "else", unsupported_case) + table_data += " }\n" + else: + table_data += json_to_table_data(internal_format, format_name, "", supported_case) + + return table_data def reject_duplicate_keys(pairs): found_keys = {} @@ -505,27 +343,17 @@ def reject_duplicate_keys(pairs): found_keys[key] = value return found_keys -with open('texture_format_map.json') as texture_format_map_file: - with open('texture_format_data.json') as texture_format_json_file: - texture_format_map = texture_format_map_file.read() - texture_format_data = texture_format_json_file.read() - texture_format_map_file.close() - texture_format_json_file.close() - json_map = json.loads(texture_format_map, object_pairs_hook=reject_duplicate_keys) - json_data = json.loads(texture_format_data, object_pairs_hook=reject_duplicate_keys) - - texture_format_cases = parse_json_into_switch_texture_format_string(json_map, json_data) - angle_format_cases = parse_json_into_switch_angle_format_string(json_data) - output_cpp = template_texture_format_table_autogen_cpp.format( - copyright_year=date.today().year, - texture_format_info_cases=texture_format_cases, - angle_format_info_cases=angle_format_cases) - with open('texture_format_table_autogen.cpp', 'wt') as out_file: - out_file.write(output_cpp) - out_file.close() - - enum_data = parse_json_into_angle_format_enum_string(json_data) - output_h = template_texture_format_table_autogen_h.format(angle_format_enum=enum_data) - with open('texture_format_table_autogen.h', 'wt') as out_file: - out_file.write(output_h) - out_file.close() +json_map = angle_format.load_with_override(os.path.abspath('texture_format_map.json')) + +with open('texture_format_data.json') as texture_format_json_file: + texture_format_data = texture_format_json_file.read() + texture_format_json_file.close() + json_data = json.loads(texture_format_data, object_pairs_hook=angle_format.reject_duplicate_keys) + + angle_format_cases = parse_json_into_switch_angle_format_string(json_map, json_data) + output_cpp = template_texture_format_table_autogen_cpp.format( + copyright_year=date.today().year, + angle_format_info_cases=angle_format_cases) + with open('texture_format_table_autogen.cpp', 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json deleted file mode 100644 index bef8980906e..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json +++ /dev/null @@ -1,1208 +0,0 @@ -{ - "GL_RG8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative<GLbyte,2>", - "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_SRGB8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4<GLubyte,0xFF>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative<GLbyte,4>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_R8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative<GLbyte,1>", - "dxgiFormat": "DXGI_FORMAT_R8_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative<GLbyte,4>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_R16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative<GLshort,1>", - "dxgiFormat": "DXGI_FORMAT_R16_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2SRGBA8ToSRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2RGB8A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGB32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative3To4<GLuint,0x00000001>", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_ALPHA32F_EXT": { - "GL_FLOAT": [ - { - "loadFunction": "LoadA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_R16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,1>", - "dxgiFormat": "DXGI_FORMAT_R16_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_RGB9_E5": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadRGB16FToRGB9E5", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_INT_5_9_9_9_REV": [ - { - "loadFunction": "LoadToNative<GLuint,1>", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadRGB32FToRGB9E5", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadRGB16FToRGB9E5", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_R11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACR11ToR8", - "dxgiFormat": "DXGI_FORMAT_R8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative<GLuint,4>", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_RG8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,2>", - "dxgiFormat": "DXGI_FORMAT_R8G8_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE32F_EXT": { - "GL_FLOAT": [ - { - "loadFunction": "LoadL32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2SRGB8A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_R16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative<GLhalf,1>", - "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "Load32FTo16F<1>", - "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative<GLhalf,1>", - "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_BGRA4_ANGLEX": { - "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": [ - { - "loadFunction": "LoadRGBA4ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative<GLhalf,4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "Load32FTo16F<4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative<GLhalf,4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadL8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,16>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGB": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_5_6_5": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGB5_A1": { - "GL_UNSIGNED_INT_2_10_10_10_REV": [ - { - "loadFunction": "LoadRGB10A2ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadRGB10A2ToBGR5A1", - "dxgiFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "false" - }, - { - "loadFunction": "LoadRGBA8ToBGR5A1", - "dxgiFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_5_5_5_1": [ - { - "loadFunction": "LoadRGB5A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadRGB5A1ToA1RGB5", - "dxgiFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGB16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative3To4<GLushort,0x0001>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_BGRA_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGB8_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2RGB8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative<GLfloat,4>", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative<GLint,4>", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE8_ALPHA8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadLA8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,2>", - "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB10_A2": { - "GL_UNSIGNED_INT_2_10_10_10_REV": [ - { - "loadFunction": "LoadToNative<GLuint,1>", - "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_SIGNED_RG11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACRG11SToRG8", - "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH_COMPONENT16": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadR32ToR16", - "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,1>", - "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS", - "requiresConversion": "false" - }, - { - "loadFunction": "LoadToNative<GLushort,1>", - "dxgiFormat": "DXGI_FORMAT_D16_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative3To4<GLint,0x00000001>", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "requiresConversion": "true" - } - ] - }, - "GL_R8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,1>", - "dxgiFormat": "DXGI_FORMAT_R8_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative3To4<GLfloat,gl::Float32One>", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_R11F_G11F_B10F": { - "GL_UNSIGNED_INT_10F_11F_11F_REV": [ - { - "loadFunction": "LoadToNative<GLuint,1>", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "false" - } - ], - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadRGB16FToRG11B10F", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadRGB32FToRG11B10F", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadRGB16FToRG11B10F", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4<GLubyte,0xFF>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_LUMINANCE_ALPHA": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadLA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative<GLshort,4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_R8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative<GLbyte,1>", - "dxgiFormat": "DXGI_FORMAT_R8_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_RGB8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative3To4<GLbyte,0x7F>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RG32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative<GLfloat,2>", - "dxgiFormat": "DXGI_FORMAT_R32G32_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_DEPTH_COMPONENT32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative<GLfloat,1>", - "dxgiFormat": "DXGI_FORMAT_R32_TYPELESS", - "requiresConversion": "false" - }, - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative<GLint,2>", - "dxgiFormat": "DXGI_FORMAT_R32G32_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_ALPHA8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,1>", - "dxgiFormat": "DXGI_FORMAT_A8_UNORM", - "requiresConversion": "false" - }, - { - "loadFunction": "LoadA8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RG32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative<GLuint,2>", - "dxgiFormat": "DXGI_FORMAT_R32G32_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_RGBA8_ETC2_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2RGBA8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGB8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative3To4<GLbyte,0x01>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_SRGB8_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2SRGB8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH32F_STENCIL8": { - "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": [ - { - "loadFunction": "LoadToNative<GLuint,2>", - "dxgiFormat": "DXGI_FORMAT_R32G8X24_TYPELESS", - "requiresConversion": "false" - }, - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative<GLbyte,2>", - "dxgiFormat": "DXGI_FORMAT_R8G8_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_R32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative<GLuint,1>", - "dxgiFormat": "DXGI_FORMAT_R32_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_BGR5_A1_ANGLEX": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "false" - } - ], - "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": [ - { - "loadFunction": "LoadRGB5A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RG11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACRG11ToRG8", - "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_SRGB8_ALPHA8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE_ALPHA16F_EXT": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_4_4_4_4": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_5_5_5_1": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH24_STENCIL8": { - "GL_UNSIGNED_INT_24_8": [ - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative3To4<GLshort,0x0001>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "requiresConversion": "true" - } - ] - }, - "GL_R8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,1>", - "dxgiFormat": "DXGI_FORMAT_R8_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_ALPHA": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative3To4<GLhalf,gl::Float16One>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadRGB32FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative3To4<GLhalf,gl::Float16One>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_SIGNED_R11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACR11SToR8", - "dxgiFormat": "DXGI_FORMAT_R8_SNORM", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,8>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,8>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_STENCIL_INDEX8": { - "DXGI_FORMAT_R24G8_TYPELESS": [ - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "DXGI_FORMAT_D24_UNORM_S8_UINT": [ - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_LUMINANCE_ALPHA32F_EXT": { - "GL_FLOAT": [ - { - "loadFunction": "LoadLA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGB8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4<GLubyte,0x01>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH_COMPONENT24": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_R32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative<GLint,1>", - "dxgiFormat": "DXGI_FORMAT_R32_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_DEPTH_COMPONENT32_OES": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_R32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative<GLfloat,1>", - "dxgiFormat": "DXGI_FORMAT_R32_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RG16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative<GLhalf,2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "Load32FTo16F<2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative<GLhalf,2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RGB565": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4<GLubyte,0xFF>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadRGB8ToBGR565", - "dxgiFormat": "DXGI_FORMAT_B5G6R5_UNORM", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_5_6_5": [ - { - "loadFunction": "LoadR5G6B5ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadToNative<GLushort,1>", - "dxgiFormat": "DXGI_FORMAT_B5G6R5_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE16F_EXT": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,16>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative<GLshort,2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_BGRA8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "false" - } - ] - }, - "GL_ALPHA16F_EXT": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA4": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "false" - }, - { - "loadFunction": "LoadRGBA8ToBGRA4", - "dxgiFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_4_4_4_4": [ - { - "loadFunction": "LoadRGBA4ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadRGBA4ToARGB4", - "dxgiFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative<GLubyte,4>", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadL32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB10_A2UI": { - "GL_UNSIGNED_INT_2_10_10_10_REV": [ - { - "loadFunction": "LoadToNative<GLuint,1>", - "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_ETC1_RGB8_OES": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC1RGB8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC1RGB8ToBC1", - "dxgiFormat": "DXGI_FORMAT_BC1_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_R16_EXT": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,1>", - "dxgiFormat": "DXGI_FORMAT_R16_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RG16_EXT": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB16_EXT": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative3To4<GLushort,0xFFFF>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA16_EXT": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_R16_SNORM_EXT": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,1>", - "dxgiFormat": "DXGI_FORMAT_R16_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RG16_SNORM_EXT": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB16_SNORM_EXT": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative3To4<GLushort,0x7FFF>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA16_SNORM_EXT": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative<GLushort,4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SNORM", - "requiresConversion": "false" - } - ] - } -}
\ No newline at end of file diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h deleted file mode 100644 index b17062f68dd..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// load_functions_table: -// Contains load functions table depending on internal format and dxgi format -// - -#ifndef LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ -#define LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ - -#include <map> - -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" - -namespace rx -{ - -namespace d3d11 -{ - -const std::map<GLenum, LoadImageFunctionInfo> &GetLoadFunctionsMap(GLenum internalFormat, - DXGI_FORMAT dxgiFormat); - -} // namespace d3d11 - -} // namespace rx - -#endif // LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp deleted file mode 100644 index 9b03083a926..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp +++ /dev/null @@ -1,1970 +0,0 @@ -// GENERATED FILE - DO NOT EDIT. -// Generated by gen_load_functions_table.py using data from load_functions_data.json -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// load_functions_table: -// Contains the GetLoadFunctionsMap for texture_format_util.h -// - -#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" -#include "libANGLE/renderer/d3d/loadimage.h" -#include "libANGLE/renderer/d3d/loadimage_etc.h" - -namespace rx -{ - -namespace d3d11 -{ - -namespace -{ - -// ES3 image loading functions vary based on: -// - the GL internal format (supplied to glTex*Image*D) -// - the GL data type given (supplied to glTex*Image*D) -// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D -// device's capabilities) -// This map type determines which loading function to use, based on these three parameters. -// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. -void UnimplementedLoadFunction(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - UNIMPLEMENTED(); -} - -void UnreachableLoadFunction(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - UNREACHABLE(); -} - -} // namespace - -// TODO we can replace these maps with more generated code -const std::map<GLenum, LoadImageFunctionInfo> &GetLoadFunctionsMap(GLenum internalFormat, - DXGI_FORMAT dxgiFormat) -{ - // clang-format off - switch (internalFormat) - { - case GL_ALPHA: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadA16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadA16FToRGBA16F, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadA32FToRGBA32F, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_ALPHA16F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadA16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadA16FToRGBA16F, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadA16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadA16FToRGBA16F, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_ALPHA32F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadA32FToRGBA32F, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadA32FToRGBA32F, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_ALPHA8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,1>, false) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadA8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_BGR5_A1_ANGLEX: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, true) }, - { GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_BGRA4_ANGLEX: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, true) }, - { GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_BGRA8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_BGRA_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_R11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadEACR11ToR8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RG11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadEACRG11ToRG8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGB8_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC2RGB8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC2RGB8A1ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGBA8_ETC2_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC2RGBA8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_SIGNED_R11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadEACR11SToR8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SIGNED_RG11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadEACRG11SToRG8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC2SRGBA8ToSRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SRGB8_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC2SRGB8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC2SRGB8A1ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH24_STENCIL8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_D24_UNORM_S8_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT_24_8, LoadImageFunctionInfo(LoadR32ToR24G8, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R24G8_TYPELESS: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT_24_8, LoadImageFunctionInfo(LoadR32ToR24G8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH32F_STENCIL8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G8X24_TYPELESS: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadImageFunctionInfo(LoadToNative<GLuint,2>, false) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_DEPTH_COMPONENT16: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_D16_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,1>, false) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R16_TYPELESS: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadR32ToR16, true) }, - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH_COMPONENT24: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_D24_UNORM_S8_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadR32ToR24G8, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R24G8_TYPELESS: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadR32ToR24G8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH_COMPONENT32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_TYPELESS: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadToNative<GLfloat,1>, false) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_DEPTH_COMPONENT32_OES: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadR32ToR24G8, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadR32ToR24G8, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_BC1_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC1RGB8ToBC1, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_ETC1_RGB8_OES: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadETC1RGB8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_LUMINANCE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadL16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadL16FToRGBA16F, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadL32FToRGBA32F, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE16F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadL16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadL16FToRGBA16F, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadL16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadL16FToRGBA16F, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE32F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadL32FToRGBA32F, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadL32FToRGBA32F, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE8_ALPHA8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadLA8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadLA8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadL8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadL8ToRGBA8, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE_ALPHA: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadLA16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadLA16FToRGBA16F, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadLA32FToRGBA32F, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE_ALPHA16F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadLA16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadLA16FToRGBA16F, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadLA16FToRGBA16F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadLA16FToRGBA16F, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE_ALPHA32F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadLA32FToRGBA32F, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadLA32FToRGBA32F, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_R11F_G11F_B10F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R11G11B10_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true) }, - { GL_FLOAT, LoadImageFunctionInfo(LoadRGB32FToRG11B10F, true) }, - { GL_UNSIGNED_INT_10F_11F_11F_REV, LoadImageFunctionInfo(LoadToNative<GLuint,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(Load32FTo16F<1>, true) }, - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadToNative<GLhalf,1>, false) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadToNative<GLhalf,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative<GLshort,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16_SNORM_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadToNative<GLfloat,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_INT, LoadImageFunctionInfo(LoadToNative<GLint,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadToNative<GLuint,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative<GLbyte,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative<GLbyte,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(Load32FTo16F<2>, true) }, - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadToNative<GLhalf,2>, false) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadToNative<GLhalf,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative<GLshort,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16_SNORM_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadToNative<GLfloat,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_INT, LoadImageFunctionInfo(LoadToNative<GLint,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadToNative<GLuint,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative<GLbyte,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative<GLbyte,2>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - { GL_UNSIGNED_SHORT_5_6_5, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - { GL_UNSIGNED_SHORT_5_6_5, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_RGB10_A2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R10G10B10A2_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT_2_10_10_10_REV, LoadImageFunctionInfo(LoadToNative<GLuint,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB10_A2UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R10G10B10A2_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT_2_10_10_10_REV, LoadImageFunctionInfo(LoadToNative<GLuint,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadRGB32FToRGBA16F, true) }, - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadToNative3To4<GLhalf,gl::Float16One>, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadToNative3To4<GLhalf,gl::Float16One>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative3To4<GLshort,0x0001>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative3To4<GLushort,0x0001>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative3To4<GLushort,0xFFFF>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16_SNORM_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative3To4<GLushort,0x7FFF>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadToNative3To4<GLfloat,gl::Float32One>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_INT, LoadImageFunctionInfo(LoadToNative3To4<GLint,0x00000001>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadToNative3To4<GLuint,0x00000001>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB565: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_B5G6R5_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadRGB8ToBGR565, true) }, - { GL_UNSIGNED_SHORT_5_6_5, LoadImageFunctionInfo(LoadToNative<GLushort,1>, false) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT_5_6_5, LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0xFF>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB5_A1: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_B5G5R5A1_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT_2_10_10_10_REV, LoadImageFunctionInfo(LoadRGB10A2ToBGR5A1, true) }, - { GL_UNSIGNED_SHORT_5_5_5_1, LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadRGBA8ToBGR5A1, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT_2_10_10_10_REV, LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true) }, - { GL_UNSIGNED_SHORT_5_5_5_1, LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0xFF>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative3To4<GLbyte,0x01>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0x01>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative3To4<GLbyte,0x7F>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB9_E5: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true) }, - { GL_FLOAT, LoadImageFunctionInfo(LoadRGB32FToRGB9E5, true) }, - { GL_UNSIGNED_INT_5_9_9_9_REV, LoadImageFunctionInfo(LoadToNative<GLuint,1>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - { GL_UNSIGNED_SHORT_4_4_4_4, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - { GL_UNSIGNED_SHORT_5_5_5_1, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - { GL_UNSIGNED_SHORT_4_4_4_4, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - { GL_UNSIGNED_SHORT_5_5_5_1, LoadImageFunctionInfo(UnreachableLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - case GL_RGBA16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(Load32FTo16F<4>, true) }, - { GL_HALF_FLOAT, LoadImageFunctionInfo(LoadToNative<GLhalf,4>, false) }, - { GL_HALF_FLOAT_OES, LoadImageFunctionInfo(LoadToNative<GLhalf,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative<GLshort,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA16_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA16_SNORM_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_SHORT, LoadImageFunctionInfo(LoadToNative<GLushort,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_FLOAT, LoadImageFunctionInfo(LoadToNative<GLfloat,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_INT, LoadImageFunctionInfo(LoadToNative<GLint,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_INT, LoadImageFunctionInfo(LoadToNative<GLuint,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA4: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_B4G4R4A4_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT_4_4_4_4, LoadImageFunctionInfo(LoadRGBA4ToARGB4, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadRGBA8ToBGRA4, true) }, - }; - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_SHORT_4_4_4_4, LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true) }, - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative<GLbyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UINT: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SNORM: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_BYTE, LoadImageFunctionInfo(LoadToNative<GLbyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_SRGB8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative3To4<GLubyte,0xFF>, true) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_SRGB8_ALPHA8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { GL_UNSIGNED_BYTE, LoadImageFunctionInfo(LoadToNative<GLubyte,4>, false) }, - }; - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_STENCIL_INDEX8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { DXGI_FORMAT_D24_UNORM_S8_UINT, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - { DXGI_FORMAT_R24G8_TYPELESS, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - default: - { - static const std::map<GLenum, LoadImageFunctionInfo> loadFunctionsMap = { - { DXGI_FORMAT_D24_UNORM_S8_UINT, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - { DXGI_FORMAT_R24G8_TYPELESS, LoadImageFunctionInfo(UnimplementedLoadFunction, true) }, - }; - - return loadFunctionsMap; - } - } - } - - default: - { - static std::map<GLenum, LoadImageFunctionInfo> emptyLoadFunctionsMap; - return emptyLoadFunctionsMap; - } - } - // clang-format on - -} // GetLoadFunctionsMap - -} // namespace d3d11 - -} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp index 1c5e9651d12..ad0e1085d71 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp @@ -349,8 +349,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum gl::TextureCaps textureCaps; DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel); - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); @@ -364,21 +363,21 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum } } - textureCaps.texturable = support.query(formatInfo.formatSet->texFormat, texSupportMask); + textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask); textureCaps.filterable = - support.query(formatInfo.formatSet->srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); + support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); textureCaps.renderable = - (support.query(formatInfo.formatSet->rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) || - (support.query(formatInfo.formatSet->dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)); + (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) || + (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)); DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN; - if (formatInfo.formatSet->dsvFormat != DXGI_FORMAT_UNKNOWN) + if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { - renderFormat = formatInfo.formatSet->dsvFormat; + renderFormat = formatInfo.dsvFormat; } - else if (formatInfo.formatSet->rtvFormat != DXGI_FORMAT_UNKNOWN) + else if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) { - renderFormat = formatInfo.formatSet->rtvFormat; + renderFormat = formatInfo.rtvFormat; } if (renderFormat != DXGI_FORMAT_UNKNOWN && support.query(renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) @@ -754,14 +753,13 @@ static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) { - // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass switch (featureLevel) { case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers case D3D_FEATURE_LEVEL_9_3: @@ -798,7 +796,7 @@ static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) { - // According to The OpenGL ES Shading Language specifications + // According to The OpenGL ES Shading Language specifications // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21) // built-in special variables (e.g. gl_FragCoord, or gl_PointCoord) // which are statically used in the shader should be included in the variable packing algorithm. @@ -821,8 +819,6 @@ static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) default: UNREACHABLE(); return 0; } - - return 1; } static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) @@ -1242,6 +1238,7 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons extensions->packSubimage = true; extensions->lossyETCDecode = true; extensions->syncQuery = GetEventQuerySupport(featureLevel); + extensions->copyTexture = true; // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing. // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't support gl_FrontFacing. @@ -1370,11 +1367,11 @@ void GenerateInitialTextureData(GLint internalFormat, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData, std::vector<std::vector<BYTE>> *outData) { - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); + const d3d11::Format &d3dFormatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); ASSERT(d3dFormatInfo.dataInitializerFunction != NULL); const d3d11::DXGIFormatSize &dxgiFormatInfo = - d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.formatSet->texFormat); + d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat); outSubresourceData->resize(mipLevels); outData->resize(mipLevels); @@ -1509,13 +1506,48 @@ ID3D11BlendState *LazyBlendState::resolve(ID3D11Device *device) return mResource; } -WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel) +WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps, + const DXGI_ADAPTER_DESC &adapterDesc) { + bool is9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); + WorkaroundsD3D workarounds; workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = true; - workarounds.zeroMaxLodWorkaround = (featureLevel <= D3D_FEATURE_LEVEL_9_3); - workarounds.useInstancedPointSpriteEmulation = (featureLevel <= D3D_FEATURE_LEVEL_9_3); + workarounds.zeroMaxLodWorkaround = is9_3; + workarounds.useInstancedPointSpriteEmulation = is9_3; + + // TODO(jmadill): Narrow problematic driver range. + if (adapterDesc.VendorId == VENDOR_ID_NVIDIA) + { + if (deviceCaps.driverVersion.valid()) + { + WORD part1 = HIWORD(deviceCaps.driverVersion.value().LowPart); + WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart); + + // Disable the workaround to fix a second driver bug on newer NVIDIA. + workarounds.depthStencilBlitExtraCopy = (part1 <= 13u && part2 < 6881); + } + else + { + workarounds.depthStencilBlitExtraCopy = true; + } + } + + // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. + workarounds.expandIntegerPowExpressions = true; + + workarounds.flushAfterEndingTransformFeedback = (adapterDesc.VendorId == VENDOR_ID_NVIDIA); + workarounds.getDimensionsIgnoresBaseLevel = (adapterDesc.VendorId == VENDOR_ID_NVIDIA); + + workarounds.preAddTexelFetchOffsets = (adapterDesc.VendorId == VENDOR_ID_INTEL); + workarounds.disableB5G6R5Support = (adapterDesc.VendorId == VENDOR_ID_INTEL); + workarounds.rewriteUnaryMinusOperator = (adapterDesc.VendorId == VENDOR_ID_INTEL); + workarounds.emulateIsnanFloat = (adapterDesc.VendorId == VENDOR_ID_INTEL); + + // TODO(jmadill): Disable when we have a fixed driver version. + workarounds.emulateTinyStencilTextures = (adapterDesc.VendorId == VENDOR_ID_AMD); + return workarounds; } @@ -1534,7 +1566,7 @@ void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t TextureHelper11::TextureHelper11() : mTextureType(GL_NONE), mFormat(DXGI_FORMAT_UNKNOWN), - mANGLEFormat(d3d11::ANGLE_FORMAT_NONE), + mFormatSet(nullptr), mSampleCount(0), mTexture2D(nullptr), mTexture3D(nullptr) @@ -1545,7 +1577,7 @@ TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) : mTextureType(toCopy.mTextureType), mExtents(toCopy.mExtents), mFormat(toCopy.mFormat), - mANGLEFormat(toCopy.mANGLEFormat), + mFormatSet(toCopy.mFormatSet), mSampleCount(toCopy.mSampleCount), mTexture2D(toCopy.mTexture2D), mTexture3D(toCopy.mTexture3D) @@ -1555,10 +1587,10 @@ TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) // static TextureHelper11 TextureHelper11::MakeAndReference(ID3D11Resource *genericResource, - d3d11::ANGLEFormat angleFormat) + const d3d11::Format &formatSet) { TextureHelper11 newHelper; - newHelper.mANGLEFormat = angleFormat; + newHelper.mFormatSet = &formatSet; newHelper.mTexture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(genericResource); newHelper.mTexture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(genericResource); newHelper.mTextureType = newHelper.mTexture2D ? GL_TEXTURE_2D : GL_TEXTURE_3D; @@ -1568,10 +1600,10 @@ TextureHelper11 TextureHelper11::MakeAndReference(ID3D11Resource *genericResourc // static TextureHelper11 TextureHelper11::MakeAndPossess2D(ID3D11Texture2D *texToOwn, - d3d11::ANGLEFormat angleFormat) + const d3d11::Format &formatSet) { TextureHelper11 newHelper; - newHelper.mANGLEFormat = angleFormat; + newHelper.mFormatSet = &formatSet; newHelper.mTexture2D = texToOwn; newHelper.mTextureType = GL_TEXTURE_2D; newHelper.initDesc(); @@ -1580,10 +1612,10 @@ TextureHelper11 TextureHelper11::MakeAndPossess2D(ID3D11Texture2D *texToOwn, // static TextureHelper11 TextureHelper11::MakeAndPossess3D(ID3D11Texture3D *texToOwn, - d3d11::ANGLEFormat angleFormat) + const d3d11::Format &formatSet) { TextureHelper11 newHelper; - newHelper.mANGLEFormat = angleFormat; + newHelper.mFormatSet = &formatSet; newHelper.mTexture3D = texToOwn; newHelper.mTextureType = GL_TEXTURE_3D; newHelper.initDesc(); @@ -1616,7 +1648,7 @@ void TextureHelper11::initDesc() mFormat = desc3D.Format; mSampleCount = 1; } - ASSERT(mFormat == d3d11::GetANGLEFormatSet(mANGLEFormat).texFormat); + ASSERT(mFormatSet && mFormat == mFormatSet->texFormat); } TextureHelper11::~TextureHelper11() @@ -1639,10 +1671,10 @@ TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&texture) mTextureType = texture.mTextureType; mExtents = texture.mExtents; mFormat = texture.mFormat; - mANGLEFormat = texture.mANGLEFormat; + mFormatSet = texture.mFormatSet; mSampleCount = texture.mSampleCount; mTexture2D = texture.mTexture2D; - mTexture3D = texture.mTexture3D; + mTexture3D = texture.mTexture3D; texture.reset(); return *this; } @@ -1652,19 +1684,23 @@ void TextureHelper11::reset() mTextureType = GL_NONE; mExtents = gl::Extents(); mFormat = DXGI_FORMAT_UNKNOWN; + mFormatSet = nullptr; mSampleCount = 0; mTexture2D = nullptr; mTexture3D = nullptr; } +bool TextureHelper11::valid() const +{ + return (mTextureType != GL_NONE); +} + gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, - d3d11::ANGLEFormat angleFormat, + const d3d11::Format &formatSet, const gl::Extents &size, StagingAccess readAndWriteAccess, ID3D11Device *device) { - const auto &formatSet = d3d11::GetANGLEFormatSet(angleFormat); - if (textureType == GL_TEXTURE_2D) { D3D11_TEXTURE2D_DESC stagingDesc; @@ -1693,7 +1729,7 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, result); } - return TextureHelper11::MakeAndPossess2D(stagingTex, angleFormat); + return TextureHelper11::MakeAndPossess2D(stagingTex, formatSet); } ASSERT(textureType == GL_TEXTURE_3D); @@ -1716,7 +1752,7 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, result); } - return TextureHelper11::MakeAndPossess3D(stagingTex, angleFormat); + return TextureHelper11::MakeAndPossess3D(stagingTex, formatSet); } bool UsePresentPathFast(const Renderer11 *renderer, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h index de01dbe30c7..2690fc6f52d 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h @@ -14,7 +14,8 @@ #include <functional> #include <vector> -#include "libANGLE/angletypes.h" +#include "common/Color.h" + #include "libANGLE/Caps.h" #include "libANGLE/Error.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" @@ -345,7 +346,8 @@ void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, c } } -WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel); +WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps, + const DXGI_ADAPTER_DESC &adapterDesc); enum ReservedConstantBufferSlot { @@ -368,20 +370,21 @@ class TextureHelper11 : angle::NonCopyable TextureHelper11 &operator=(TextureHelper11 &&texture); static TextureHelper11 MakeAndReference(ID3D11Resource *genericResource, - d3d11::ANGLEFormat angleFormat); + const d3d11::Format &formatSet); static TextureHelper11 MakeAndPossess2D(ID3D11Texture2D *texToOwn, - d3d11::ANGLEFormat angleFormat); + const d3d11::Format &formatSet); static TextureHelper11 MakeAndPossess3D(ID3D11Texture3D *texToOwn, - d3d11::ANGLEFormat angleFormat); + const d3d11::Format &formatSet); GLenum getTextureType() const { return mTextureType; } gl::Extents getExtents() const { return mExtents; } DXGI_FORMAT getFormat() const { return mFormat; } - d3d11::ANGLEFormat getANGLEFormat() const { return mANGLEFormat; } + const d3d11::Format &getFormatSet() const { return *mFormatSet; } int getSampleCount() const { return mSampleCount; } ID3D11Texture2D *getTexture2D() const { return mTexture2D; } ID3D11Texture3D *getTexture3D() const { return mTexture3D; } ID3D11Resource *getResource() const; + bool valid() const; private: void reset(); @@ -390,7 +393,7 @@ class TextureHelper11 : angle::NonCopyable GLenum mTextureType; gl::Extents mExtents; DXGI_FORMAT mFormat; - d3d11::ANGLEFormat mANGLEFormat; + const d3d11::Format *mFormatSet; int mSampleCount; ID3D11Texture2D *mTexture2D; ID3D11Texture3D *mTexture3D; @@ -403,7 +406,7 @@ enum class StagingAccess }; gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, - d3d11::ANGLEFormat angleFormat, + const d3d11::Format &formatSet, const gl::Extents &size, StagingAccess readAndWriteAccess, ID3D11Device *device); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl index 8671c39fb7a..21024e3b77d 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl @@ -21,6 +21,23 @@ float4 PS_PassthroughRGBA2D(in float4 inPosition : SV_POSITION, in float2 inTexC return TextureF.Sample(Sampler, inTexCoord).rgba; } +float4 PS_PassthroughRGBAPremultiply2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb *= color.a; + return color; +} + +float4 PS_PassthroughRGBAUnmultiply2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + return color; +} + uint4 PS_PassthroughRGBA2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 { uint2 size; @@ -42,6 +59,23 @@ float4 PS_PassthroughRGB2D(in float4 inPosition : SV_POSITION, in float2 inTexCo return float4(TextureF.Sample(Sampler, inTexCoord).rgb, 1.0f); } +float4 PS_PassthroughRGBPremultiply2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb *= color.a; + return color; +} + +float4 PS_PassthroughRGBUnmultiply2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + return color; +} + uint4 PS_PassthroughRGB2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 { uint2 size; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl new file mode 100644 index 00000000000..70df1d1b6e0 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl @@ -0,0 +1,56 @@ +static const float2 g_Corners[6] = +{ + float2(-1.0f, 1.0f), + float2( 1.0f, -1.0f), + float2(-1.0f, -1.0f), + float2(-1.0f, 1.0f), + float2( 1.0f, 1.0f), + float2( 1.0f, -1.0f), +}; + +void VS_ResolveDepthStencil(in uint id : SV_VertexID, + out float4 position : SV_Position, + out float2 texCoord : TEXCOORD0) +{ + float2 corner = g_Corners[id]; + position = float4(corner.x, corner.y, 0.0f, 1.0f); + texCoord = float2((corner.x + 1.0f) * 0.5f, (-corner.y + 1.0f) * 0.5f); +} + +Texture2DMS<float> Depth : register(t0); +Texture2DMS<uint2> Stencil : register(t1); + +void PS_ResolveDepth(in float4 position : SV_Position, + in float2 texCoord : TEXCOORD0, + out float depth : SV_Target0) +{ + // MS samplers must use Load + uint width, height, samples; + Depth.GetDimensions(width, height, samples); + uint2 coord = uint2(texCoord.x * float(width), texCoord.y * float(height)); + depth = Depth.Load(coord, 0).r; +} + +void PS_ResolveDepthStencil(in float4 position : SV_Position, + in float2 texCoord : TEXCOORD0, + out float2 depthStencil : SV_Target0) +{ + // MS samplers must use Load + uint width, height, samples; + Depth.GetDimensions(width, height, samples); + uint2 coord = uint2(texCoord.x * float(width), texCoord.y * float(height)); + depthStencil.r = Depth.Load(coord, 0).r; + depthStencil.g = float(Stencil.Load(coord, 0).g); +} + +void PS_ResolveStencil(in float4 position : SV_Position, + in float2 texCoord : TEXCOORD0, + out float2 stencil : SV_Target0) +{ + // MS samplers must use Load + uint width, height, samples; + Stencil.GetDimensions(width, height, samples); + uint2 coord = uint2(texCoord.x * float(width), texCoord.y * float(height)); + stencil.r = 0.0f; + stencil.g = float(Stencil.Load(coord, 0).g); +} diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbapremultiply2d11ps.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbapremultiply2d11ps.h new file mode 100644 index 00000000000..e7285a6bca6 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbapremultiply2d11ps.h @@ -0,0 +1,101 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0.xyz, r0.w, r0 + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBAPremultiply2D[] = { + 68, 88, 66, 67, 139, 254, 84, 241, 202, 33, 132, 221, 123, 19, 241, 182, 75, 155, 177, + 115, 1, 0, 0, 0, 8, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 180, 0, + 0, 0, 88, 1, 0, 0, 212, 1, 0, 0, 124, 2, 0, 0, 212, 2, 0, 0, 65, + 111, 110, 57, 116, 0, 0, 0, 116, 0, 0, 0, 0, 2, 255, 255, 76, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, + 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, + 0, 0, 7, 128, 0, 0, 255, 128, 0, 0, 228, 128, 1, 0, 0, 2, 0, 8, 15, + 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, 0, + 0, 0, 39, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, + 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, + 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, + 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, 52, 0, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, + 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbaunmultiply2d11ps.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbaunmultiply2d11ps.h new file mode 100644 index 00000000000..d3b8b6a8424 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbaunmultiply2d11ps.h @@ -0,0 +1,110 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + rcp r1.w, r0.w + mul r1.xyz, r0, r1.w + cmp r0.xyz, -r0.w, r0, r1 + mov oC0, r0 + +// approximately 5 instruction slots used (1 texture, 4 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBAUnmultiply2D[] = { + 68, 88, 66, 67, 180, 87, 43, 111, 255, 135, 28, 224, 42, 85, 197, 16, 17, 172, 176, + 70, 1, 0, 0, 0, 104, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 212, 0, + 0, 0, 184, 1, 0, 0, 52, 2, 0, 0, 220, 2, 0, 0, 52, 3, 0, 0, 65, + 111, 110, 57, 148, 0, 0, 0, 148, 0, 0, 0, 0, 2, 255, 255, 108, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, + 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 6, 0, 0, 2, + 1, 0, 8, 128, 0, 0, 255, 128, 5, 0, 0, 3, 1, 0, 7, 128, 0, 0, 228, + 128, 1, 0, 255, 128, 88, 0, 0, 4, 0, 0, 7, 128, 0, 0, 255, 129, 0, 0, + 228, 128, 1, 0, 228, 128, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, + 255, 0, 0, 83, 72, 68, 82, 220, 0, 0, 0, 64, 0, 0, 0, 55, 0, 0, 0, + 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, + 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, + 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, + 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, + 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, + 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, + 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, 56, 52, 0, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, + 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, + 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbpremultiply2d11ps.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbpremultiply2d11ps.h new file mode 100644 index 00000000000..9af002d4465 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbpremultiply2d11ps.h @@ -0,0 +1,101 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + mul r0.xyz, r0.w, r0 + mov oC0, r0 + +// approximately 3 instruction slots used (1 texture, 2 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul o0.xyz, r0.wwww, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBPremultiply2D[] = { + 68, 88, 66, 67, 139, 254, 84, 241, 202, 33, 132, 221, 123, 19, 241, 182, 75, 155, 177, + 115, 1, 0, 0, 0, 8, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 180, 0, + 0, 0, 88, 1, 0, 0, 212, 1, 0, 0, 124, 2, 0, 0, 212, 2, 0, 0, 65, + 111, 110, 57, 116, 0, 0, 0, 116, 0, 0, 0, 0, 2, 255, 255, 76, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, + 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, + 0, 0, 7, 128, 0, 0, 255, 128, 0, 0, 228, 128, 1, 0, 0, 2, 0, 8, 15, + 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, 0, + 0, 0, 39, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, + 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, + 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, + 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, + 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 0, 0, 0, 0, + 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, + 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, + 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, 97, + 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, 48, + 48, 46, 49, 54, 51, 56, 52, 0, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, + 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbunmultiply2d11ps.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbunmultiply2d11ps.h new file mode 100644 index 00000000000..2cde26481c1 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbunmultiply2d11ps.h @@ -0,0 +1,110 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Sampler sampler NA NA 0 1 +// TextureF texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + dcl t0.xy + dcl_2d s0 + texld r0, t0, s0 + rcp r1.w, r0.w + mul r1.xyz, r0, r1.w + cmp r0.xyz, -r0.w, r0, r1 + mov oC0, r0 + +// approximately 5 instruction slots used (1 texture, 4 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.xyzw +dcl_temps 2 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +lt r1.x, l(0.000000), r0.w +div r1.yzw, r0.xxyz, r0.wwww +movc o0.xyz, r1.xxxx, r1.yzwy, r0.xyzx +mov o0.w, r0.w +ret +// Approximately 6 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBUnmultiply2D[] = { + 68, 88, 66, 67, 180, 87, 43, 111, 255, 135, 28, 224, 42, 85, 197, 16, 17, 172, 176, + 70, 1, 0, 0, 0, 104, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 212, 0, + 0, 0, 184, 1, 0, 0, 52, 2, 0, 0, 220, 2, 0, 0, 52, 3, 0, 0, 65, + 111, 110, 57, 148, 0, 0, 0, 148, 0, 0, 0, 0, 2, 255, 255, 108, 0, 0, 0, + 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, + 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, + 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 6, 0, 0, 2, + 1, 0, 8, 128, 0, 0, 255, 128, 5, 0, 0, 3, 1, 0, 7, 128, 0, 0, 228, + 128, 1, 0, 255, 128, 88, 0, 0, 4, 0, 0, 7, 128, 0, 0, 255, 129, 0, 0, + 228, 128, 1, 0, 228, 128, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, + 255, 0, 0, 83, 72, 68, 82, 220, 0, 0, 0, 64, 0, 0, 0, 55, 0, 0, 0, + 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, + 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, + 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, + 0, 49, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 14, 0, 0, 7, 226, 0, 16, 0, 1, + 0, 0, 0, 6, 9, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0, + 55, 0, 0, 9, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, + 0, 150, 7, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 54, 0, + 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, + 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, + 4, 255, 255, 0, 1, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 100, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, + 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 83, + 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 0, 77, 105, 99, + 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, + 48, 48, 46, 49, 54, 51, 56, 52, 0, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, + 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, + 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, + 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h new file mode 100644 index 00000000000..f173cff07d1 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h @@ -0,0 +1,82 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Depth texture float 2dMS 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 x 0 TARGET float x +// +ps_4_1 +dcl_globalFlags refactoringAllowed +dcl_resource_texture2dms(0) (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_output o0.x +dcl_temps 1 +resinfo_uint r0.xy, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftou r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ldms r0.x, r0.xyzw, t0.xyzw, l(0) +mov o0.x, r0.x +ret +// Approximately 8 instruction slots used +#endif + +const BYTE g_PS_ResolveDepth[] = { + 68, 88, 66, 67, 205, 219, 191, 201, 103, 134, 243, 76, 11, 91, 23, 182, 42, 8, 17, + 173, 1, 0, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 176, 0, + 0, 0, 8, 1, 0, 0, 60, 1, 0, 0, 60, 2, 0, 0, 82, 68, 69, 70, 116, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 1, 4, 255, 255, 0, 1, 0, 0, 66, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 68, 101, 112, 116, 104, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, + 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, 80, 111, 115, 105, + 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, + 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 14, 0, 0, + 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 248, 0, 0, + 0, 65, 0, 0, 0, 62, 0, 0, 0, 106, 8, 0, 1, 88, 32, 0, 4, 0, 112, + 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, + 0, 0, 0, 101, 0, 0, 3, 18, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, + 1, 0, 0, 0, 61, 16, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, + 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 50, + 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, + 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, + 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, + 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h new file mode 100644 index 00000000000..b2c0b62f006 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h @@ -0,0 +1,92 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Depth texture float 2dMS 0 1 +// Stencil texture uint2 2dMS 1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xy 0 TARGET float xy +// +ps_4_1 +dcl_globalFlags refactoringAllowed +dcl_resource_texture2dms(0) (float,float,float,float) t0 +dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1 +dcl_input_ps linear v1.xy +dcl_output o0.xy +dcl_temps 1 +resinfo_uint r0.xy, l(0), t0.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftou r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ldms r0.z, r0.xyzw, t1.xzyw, l(0) +ldms r0.x, r0.xyww, t0.xyzw, l(0) +mov o0.x, r0.x +utof o0.y, r0.z +ret +// Approximately 10 instruction slots used +#endif + +const BYTE g_PS_ResolveDepthStencil[] = { + 68, 88, 66, 67, 229, 191, 254, 12, 10, 19, 181, 162, 222, 203, 244, 146, 104, 226, 195, + 177, 1, 0, 0, 0, 40, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 216, 0, + 0, 0, 48, 1, 0, 0, 100, 1, 0, 0, 172, 2, 0, 0, 82, 68, 69, 70, 156, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, + 1, 4, 255, 255, 0, 1, 0, 0, 106, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, + 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 98, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, + 68, 101, 112, 116, 104, 0, 83, 116, 101, 110, 99, 105, 108, 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, 48, 48, + 46, 49, 54, 51, 56, 52, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, + 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, 80, 111, + 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, + 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, + 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 64, + 1, 0, 0, 65, 0, 0, 0, 80, 0, 0, 0, 106, 8, 0, 1, 88, 32, 0, 4, + 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 88, 32, 0, 4, 0, 112, 16, + 0, 1, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, + 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, + 0, 0, 0, 61, 16, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, 50, 0, 16, + 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, + 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, + 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, + 0, 9, 66, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 134, + 125, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 46, 0, 0, 9, + 18, 0, 16, 0, 0, 0, 0, 0, 70, 15, 16, 0, 0, 0, 0, 0, 70, 126, 16, + 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 32, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 86, 0, 0, 5, 34, + 32, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, + 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h new file mode 100644 index 00000000000..1e907956ce0 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h @@ -0,0 +1,84 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_VertexID 0 x 0 VERTID uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 xy 1 NONE float xy +// +vs_4_1 +dcl_globalFlags refactoringAllowed +dcl_immediateConstantBuffer { { -1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0}, + { -1.000000, -1.000000, 0, 0}, + { -1.000000, 1.000000, 0, 0}, + { 1.000000, 1.000000, 0, 0}, + { 1.000000, -1.000000, 0, 0} } +dcl_input_sgv v0.x, vertex_id +dcl_output_siv o0.xyzw, position +dcl_output o1.xy +dcl_temps 1 +mov o0.zw, l(0,0,0,1.000000) +mov r0.x, v0.x +mov o0.xy, icb[r0.x + 0].xyxx +add r0.y, l(1.000000), icb[r0.x + 0].x +add r0.x, l(1.000000), -icb[r0.x + 0].y +mul o1.xy, r0.yxyy, l(0.500000, 0.500000, 0.000000, 0.000000) +ret +// Approximately 7 instruction slots used +#endif + +const BYTE g_VS_ResolveDepthStencil[] = { + 68, 88, 66, 67, 205, 15, 103, 70, 202, 235, 195, 98, 255, 82, 84, 239, 130, 6, 12, + 104, 1, 0, 0, 0, 0, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 140, 0, + 0, 0, 192, 0, 0, 0, 24, 1, 0, 0, 132, 2, 0, 0, 82, 68, 69, 70, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, + 1, 4, 254, 255, 0, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, + 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, + 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, 48, 48, 46, 49, + 54, 51, 56, 52, 0, 171, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, + 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 86, 101, 114, 116, 101, 120, 73, + 68, 0, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, + 0, 1, 0, 0, 0, 3, 12, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 83, 72, 68, 82, 100, + 1, 0, 0, 65, 0, 1, 0, 89, 0, 0, 0, 106, 8, 0, 1, 53, 24, 0, 0, + 26, 0, 0, 0, 0, 0, 128, 191, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128, 191, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, + 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 191, 0, 0, 0, + 0, 0, 0, 0, 0, 96, 0, 0, 4, 18, 16, 16, 0, 0, 0, 0, 0, 6, 0, + 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, + 0, 0, 3, 50, 32, 16, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, + 54, 0, 0, 8, 194, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 18, 0, + 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 50, + 32, 16, 0, 0, 0, 0, 0, 70, 144, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 34, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, + 63, 10, 144, 144, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 18, 0, + 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 26, 144, 144, 128, 65, + 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 50, 32, 16, 0, + 1, 0, 0, 0, 22, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, + 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h new file mode 100644 index 00000000000..ea43731b5fa --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h @@ -0,0 +1,84 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Stencil texture uint2 2dMS 1 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 xy 1 NONE float xy +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xy 0 TARGET float xy +// +ps_4_1 +dcl_globalFlags refactoringAllowed +dcl_resource_texture2dms(0) (uint,uint,uint,uint) t1 +dcl_input_ps linear v1.xy +dcl_output o0.xy +dcl_temps 1 +resinfo_uint r0.xy, l(0), t1.xyzw +utof r0.xy, r0.xyxx +mul r0.xy, r0.xyxx, v1.xyxx +ftou r0.xy, r0.xyxx +mov r0.zw, l(0,0,0,0) +ldms r0.x, r0.xyzw, t1.yxzw, l(0) +utof o0.y, r0.x +mov o0.x, l(0) +ret +// Approximately 9 instruction slots used +#endif + +const BYTE g_PS_ResolveStencil[] = { + 68, 88, 66, 67, 122, 29, 34, 146, 254, 203, 175, 97, 151, 254, 255, 190, 91, 40, 55, + 118, 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 180, 0, + 0, 0, 12, 1, 0, 0, 64, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 120, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 1, 4, 255, 255, 0, 1, 0, 0, 68, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, + 0, 4, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 5, 0, 0, 0, 83, 116, 101, 110, 99, 105, 108, 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 54, 46, 51, 46, 57, 54, 48, 48, + 46, 49, 54, 51, 56, 52, 0, 171, 171, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, + 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, + 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, + 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 3, 12, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, + 82, 12, 1, 0, 0, 65, 0, 0, 0, 67, 0, 0, 0, 106, 8, 0, 1, 88, 32, + 0, 4, 0, 112, 16, 0, 1, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 50, + 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 50, 0, 16, 0, 0, 0, 0, + 0, 1, 64, 0, 0, 0, 0, 0, 0, 70, 126, 16, 0, 1, 0, 0, 0, 86, 0, + 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 56, + 0, 0, 7, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, 0, 0, 28, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, + 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 46, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, + 0, 0, 0, 0, 22, 126, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, + 0, 86, 0, 0, 5, 34, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 18, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, + 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat index 652c5eae90c..657a1c02480 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/shaders/generate_shaders.bat @@ -20,7 +20,7 @@ if "%1" == "release" ( ) :: Shaders for OpenGL ES 2.0 and OpenGL ES 3.0+ -:: | Input file | Entry point | Type | Output file | Debug | +:: | Input file | Entry point | Type | Output file | Debug | call:BuildShader Passthrough2D11.hlsl VS_Passthrough2D vs_4_0_level_9_3 compiled\passthrough2d11vs.h %debug% call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2D ps_4_0_level_9_3 compiled\passthroughrgba2d11ps.h %debug% call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2D ps_4_0_level_9_3 compiled\passthroughrgb2d11ps.h %debug% @@ -29,64 +29,73 @@ call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2D ps_4_0_level_9_3 call:BuildShader Passthrough2D11.hlsl PS_PassthroughLum2D ps_4_0_level_9_3 compiled\passthroughlum2d11ps.h %debug% call:BuildShader Passthrough2D11.hlsl PS_PassthroughLumAlpha2D ps_4_0_level_9_3 compiled\passthroughlumalpha2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBAPremultiply2D ps_4_0_level_9_3 compiled\passthroughrgbapremultiply2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBAUnmultiply2D ps_4_0_level_9_3 compiled\passthroughrgbaunmultiply2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBPremultiply2D ps_4_0_level_9_3 compiled\passthroughrgbpremultiply2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBUnmultiply2D ps_4_0_level_9_3 compiled\passthroughrgbunmultiply2d11ps.h %debug% + call:BuildShader Clear11.hlsl VS_ClearFloat vs_4_0_level_9_3 compiled\clearfloat11vs.h %debug% call:BuildShader Clear11.hlsl PS_ClearFloat_FL9 ps_4_0_level_9_3 compiled\clearfloat11_fl9ps.h %debug% call:BuildShader Clear11.hlsl PS_ClearFloat ps_4_0 compiled\clearfloat11ps.h %debug% :: Shaders for OpenGL ES 3.0+ only -:: | Input file | Entry point | Type | Output file | Debug | -call:BuildShader Passthrough2D11.hlsl PS_PassthroughDepth2D ps_4_0 compiled\passthroughdepth2d11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DUI ps_4_0 compiled\passthroughrgba2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DI ps_4_0 compiled\passthroughrgba2di11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DUI ps_4_0 compiled\passthroughrgb2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DI ps_4_0 compiled\passthroughrgb2di11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DUI ps_4_0 compiled\passthroughrg2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DI ps_4_0 compiled\passthroughrg2di11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DUI ps_4_0 compiled\passthroughr2dui11ps.h %debug% -call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DI ps_4_0 compiled\passthroughr2di11ps.h %debug% - - -call:BuildShader Passthrough3D11.hlsl VS_Passthrough3D vs_4_0 compiled\passthrough3d11vs.h %debug% -call:BuildShader Passthrough3D11.hlsl GS_Passthrough3D gs_4_0 compiled\passthrough3d11gs.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3D ps_4_0 compiled\passthroughrgba3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DUI ps_4_0 compiled\passthroughrgba3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DI ps_4_0 compiled\passthroughrgba3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3D ps_4_0 compiled\passthroughrgb3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DUI ps_4_0 compiled\passthroughrgb3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DI ps_4_0 compiled\passthroughrgb3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3D ps_4_0 compiled\passthroughrg3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DUI ps_4_0 compiled\passthroughrg3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DI ps_4_0 compiled\passthroughrg3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3D ps_4_0 compiled\passthroughr3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DUI ps_4_0 compiled\passthroughr3dui11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DI ps_4_0 compiled\passthroughr3di11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughLum3D ps_4_0 compiled\passthroughlum3d11ps.h %debug% -call:BuildShader Passthrough3D11.hlsl PS_PassthroughLumAlpha3D ps_4_0 compiled\passthroughlumalpha3d11ps.h %debug% - -call:BuildShader Swizzle11.hlsl PS_SwizzleF2D ps_4_0 compiled\swizzlef2dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleI2D ps_4_0 compiled\swizzlei2dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleUI2D ps_4_0 compiled\swizzleui2dps.h %debug% - -call:BuildShader Swizzle11.hlsl PS_SwizzleF3D ps_4_0 compiled\swizzlef3dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleI3D ps_4_0 compiled\swizzlei3dps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleUI3D ps_4_0 compiled\swizzleui3dps.h %debug% - -call:BuildShader Swizzle11.hlsl PS_SwizzleF2DArray ps_4_0 compiled\swizzlef2darrayps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleI2DArray ps_4_0 compiled\swizzlei2darrayps.h %debug% -call:BuildShader Swizzle11.hlsl PS_SwizzleUI2DArray ps_4_0 compiled\swizzleui2darrayps.h %debug% - -call:BuildShader Clear11.hlsl VS_ClearUint vs_4_0 compiled\clearuint11vs.h %debug% -call:BuildShader Clear11.hlsl PS_ClearUint ps_4_0 compiled\clearuint11ps.h %debug% - -call:BuildShader Clear11.hlsl VS_ClearSint vs_4_0 compiled\clearsint11vs.h %debug% -call:BuildShader Clear11.hlsl PS_ClearSint ps_4_0 compiled\clearsint11ps.h %debug% - -call:BuildShader BufferToTexture11.hlsl VS_BufferToTexture vs_4_0 compiled/buffertotexture11_vs.h %debug% -call:BuildShader BufferToTexture11.hlsl GS_BufferToTexture gs_4_0 compiled/buffertotexture11_gs.h %debug% -call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4F ps_4_0 compiled/buffertotexture11_ps_4f.h %debug% -call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4I ps_4_0 compiled/buffertotexture11_ps_4i.h %debug% -call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4UI ps_4_0 compiled/buffertotexture11_ps_4ui.h %debug% +:: | Input file | Entry point | Type | Output file | Debug | +call:BuildShader Passthrough2D11.hlsl PS_PassthroughDepth2D ps_4_0 compiled\passthroughdepth2d11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DUI ps_4_0 compiled\passthroughrgba2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGBA2DI ps_4_0 compiled\passthroughrgba2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DUI ps_4_0 compiled\passthroughrgb2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRGB2DI ps_4_0 compiled\passthroughrgb2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DUI ps_4_0 compiled\passthroughrg2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughRG2DI ps_4_0 compiled\passthroughrg2di11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DUI ps_4_0 compiled\passthroughr2dui11ps.h %debug% +call:BuildShader Passthrough2D11.hlsl PS_PassthroughR2DI ps_4_0 compiled\passthroughr2di11ps.h %debug% + +call:BuildShader Passthrough3D11.hlsl VS_Passthrough3D vs_4_0 compiled\passthrough3d11vs.h %debug% +call:BuildShader Passthrough3D11.hlsl GS_Passthrough3D gs_4_0 compiled\passthrough3d11gs.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3D ps_4_0 compiled\passthroughrgba3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DUI ps_4_0 compiled\passthroughrgba3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGBA3DI ps_4_0 compiled\passthroughrgba3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3D ps_4_0 compiled\passthroughrgb3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DUI ps_4_0 compiled\passthroughrgb3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRGB3DI ps_4_0 compiled\passthroughrgb3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3D ps_4_0 compiled\passthroughrg3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DUI ps_4_0 compiled\passthroughrg3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughRG3DI ps_4_0 compiled\passthroughrg3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3D ps_4_0 compiled\passthroughr3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DUI ps_4_0 compiled\passthroughr3dui11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughR3DI ps_4_0 compiled\passthroughr3di11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughLum3D ps_4_0 compiled\passthroughlum3d11ps.h %debug% +call:BuildShader Passthrough3D11.hlsl PS_PassthroughLumAlpha3D ps_4_0 compiled\passthroughlumalpha3d11ps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF2D ps_4_0 compiled\swizzlef2dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI2D ps_4_0 compiled\swizzlei2dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI2D ps_4_0 compiled\swizzleui2dps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF3D ps_4_0 compiled\swizzlef3dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI3D ps_4_0 compiled\swizzlei3dps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI3D ps_4_0 compiled\swizzleui3dps.h %debug% + +call:BuildShader Swizzle11.hlsl PS_SwizzleF2DArray ps_4_0 compiled\swizzlef2darrayps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleI2DArray ps_4_0 compiled\swizzlei2darrayps.h %debug% +call:BuildShader Swizzle11.hlsl PS_SwizzleUI2DArray ps_4_0 compiled\swizzleui2darrayps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearUint vs_4_0 compiled\clearuint11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearUint ps_4_0 compiled\clearuint11ps.h %debug% + +call:BuildShader Clear11.hlsl VS_ClearSint vs_4_0 compiled\clearsint11vs.h %debug% +call:BuildShader Clear11.hlsl PS_ClearSint ps_4_0 compiled\clearsint11ps.h %debug% + +call:BuildShader BufferToTexture11.hlsl VS_BufferToTexture vs_4_0 compiled/buffertotexture11_vs.h %debug% +call:BuildShader BufferToTexture11.hlsl GS_BufferToTexture gs_4_0 compiled/buffertotexture11_gs.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4F ps_4_0 compiled/buffertotexture11_ps_4f.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4I ps_4_0 compiled/buffertotexture11_ps_4i.h %debug% +call:BuildShader BufferToTexture11.hlsl PS_BufferToTexture_4UI ps_4_0 compiled/buffertotexture11_ps_4ui.h %debug% + +call:BuildShader ResolveDepthStencil.hlsl VS_ResolveDepthStencil vs_4_1 compiled/resolvedepthstencil11_vs.h %debug% +call:BuildShader ResolveDepthStencil.hlsl PS_ResolveDepth ps_4_1 compiled/resolvedepth11_ps.h %debug% +call:BuildShader ResolveDepthStencil.hlsl PS_ResolveDepthStencil ps_4_1 compiled/resolvedepthstencil11_ps.h %debug% +call:BuildShader ResolveDepthStencil.hlsl PS_ResolveStencil ps_4_1 compiled/resolvestencil11_ps.h %debug% echo. diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json index 9deb4777f98..06f7e2afd9e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json @@ -1,17 +1,17 @@ { - "ANGLE_FORMAT_NONE": { - + "NONE": { }, - "ANGLE_FORMAT_A8_UNORM": { + "A8_UNORM": { "texFormat": "DXGI_FORMAT_A8_UNORM", "srvFormat": "DXGI_FORMAT_A8_UNORM", "rtvFormat": "DXGI_FORMAT_A8_UNORM", "channels": "a", "componentType": "unorm", "bits": { "alpha": 8 }, - "glInternalFormat": "GL_ALPHA8_EXT" + "supportTest": "OnlyFL10Plus(deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" }, - "ANGLE_FORMAT_R8G8B8A8_UNORM": { + "R8G8B8A8_UNORM": { "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", @@ -20,15 +20,16 @@ "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, "glInternalFormat": "GL_RGBA8" }, - "ANGLE_FORMAT_R16G16B16A16_UNORM": { + "R16G16B16A16_UNORM": { "texFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", "srvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", "channels": "rgba", "componentType": "unorm", - "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 } + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16_EXT" }, - "ANGLE_FORMAT_R16G16B16A16_FLOAT": { + "R16G16B16A16_FLOAT": { "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", @@ -37,7 +38,7 @@ "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, "glInternalFormat": "GL_RGBA16F" }, - "ANGLE_FORMAT_R32G32B32A32_FLOAT": { + "R32G32B32A32_FLOAT": { "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", @@ -46,7 +47,7 @@ "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, "glInternalFormat": "GL_RGBA32F" }, - "ANGLE_FORMAT_B8G8R8A8_UNORM": { + "B8G8R8A8_UNORM": { "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", @@ -55,78 +56,52 @@ "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, "glInternalFormat": "GL_BGRA8_EXT" }, - "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE": { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "BC1_RGBA_UNORM_BLOCK": { + "texFormat": "DXGI_FORMAT_BC1_UNORM", + "srvFormat": "DXGI_FORMAT_BC1_UNORM", "channels": "rgba", "componentType": "unorm", - "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, - "glInternalFormat": "GL_RGBA8" + "swizzleFormat": "GL_RGBA8", + "glInternalFormat": "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" }, - "ANGLE_FORMAT_BC1_UNORM": { + "BC1_RGB_UNORM_BLOCK": { "texFormat": "DXGI_FORMAT_BC1_UNORM", "srvFormat": "DXGI_FORMAT_BC1_UNORM", "channels": "rgba", "componentType": "unorm", - "swizzleFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "swizzleFormat": "GL_RGBA8", "glInternalFormat": "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" }, - "ANGLE_FORMAT_BC2_UNORM": { + "BC2_RGBA_UNORM_BLOCK": { "texFormat": "DXGI_FORMAT_BC2_UNORM", "srvFormat": "DXGI_FORMAT_BC2_UNORM", "channels": "rgba", "componentType": "unorm", - "swizzleFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "swizzleFormat": "GL_RGBA8", "glInternalFormat": "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE" }, - "ANGLE_FORMAT_BC3_UNORM": { + "BC3_RGBA_UNORM_BLOCK": { "texFormat": "DXGI_FORMAT_BC3_UNORM", "srvFormat": "DXGI_FORMAT_BC3_UNORM", "channels": "rgba", "componentType": "unorm", - "swizzleFormat": "ANGLE_FORMAT_R8G8B8A8_UNORM", + "swizzleFormat": "GL_RGBA8", "glInternalFormat": "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE" }, - "ANGLE_FORMAT_R8_SNORM_NONRENDERABLE": { - "texFormat": "DXGI_FORMAT_R8_SNORM", - "srvFormat": "DXGI_FORMAT_R8_SNORM", - "channels": "r", - "componentType": "snorm", - "bits": { "red": 8 }, - "glInternalFormat": "GL_R8_SNORM" - }, - "ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE": { - "texFormat": "DXGI_FORMAT_R8G8_SNORM", - "srvFormat": "DXGI_FORMAT_R8G8_SNORM", - "channels": "rg", - "componentType": "snorm", - "bits": { "red": 8, "green": 8 }, - "glInternalFormat": "GL_RG8_SNORM" - }, - "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE": { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "channels": "rgba", - "componentType": "unorm", - "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, - "glInternalFormat": "GL_SRGB8_ALPHA8" - }, - "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10": { - "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "channels": "ds", - "bits": { "depth": 24, "stencil": 8 }, - "glInternalFormat": "GL_DEPTH24_STENCIL8_OES" - }, - "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3": { - "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "D24_UNORM_S8_UINT": { + "FL10Plus": { + "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", + "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS" + }, + "FL9_3": { + "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT" + }, "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", "channels": "ds", "bits": { "depth": 24, "stencil": 8 }, "glInternalFormat": "GL_DEPTH24_STENCIL8_OES" }, - "ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10": { + "D32_FLOAT_S8X24_UINT": { "texFormat": "DXGI_FORMAT_R32G8X24_TYPELESS", "srvFormat": "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS", "dsvFormat": "DXGI_FORMAT_D32_FLOAT_S8X24_UINT", @@ -134,24 +109,21 @@ "bits": { "depth": 32, "stencil": 8 }, "glInternalFormat": "GL_DEPTH32F_STENCIL8" }, - "ANGLE_FORMAT_D16_UNORM_FL10": { - "texFormat": "DXGI_FORMAT_R16_TYPELESS", - "srvFormat": "DXGI_FORMAT_R16_UNORM", - "dsvFormat": "DXGI_FORMAT_D16_UNORM", - "channels": "d", - "componentType": "unorm", - "bits": { "depth": 16 }, - "glInternalFormat": "GL_DEPTH_COMPONENT16" - }, - "ANGLE_FORMAT_D16_UNORM_FL9_3": { - "texFormat": "DXGI_FORMAT_D16_UNORM", + "D16_UNORM": { + "FL10Plus": { + "texFormat": "DXGI_FORMAT_R16_TYPELESS", + "srvFormat": "DXGI_FORMAT_R16_UNORM" + }, + "FL9_3": { + "texFormat": "DXGI_FORMAT_D16_UNORM" + }, "dsvFormat": "DXGI_FORMAT_D16_UNORM", "channels": "d", "componentType": "unorm", "bits": { "depth": 16 }, "glInternalFormat": "GL_DEPTH_COMPONENT16" }, - "ANGLE_FORMAT_D32_FLOAT": { + "D32_FLOAT": { "texFormat": "DXGI_FORMAT_R32_TYPELESS", "srvFormat": "DXGI_FORMAT_R32_FLOAT", "dsvFormat": "DXGI_FORMAT_D32_FLOAT", @@ -160,7 +132,7 @@ "bits": { "depth": 32 }, "glInternalFormat": "GL_DEPTH_COMPONENT32F" }, - "ANGLE_FORMAT_R11G11B10_FLOAT": { + "R11G11B10_FLOAT": { "texFormat": "DXGI_FORMAT_R11G11B10_FLOAT", "srvFormat": "DXGI_FORMAT_R11G11B10_FLOAT", "rtvFormat": "DXGI_FORMAT_R11G11B10_FLOAT", @@ -169,7 +141,7 @@ "bits": { "red": 11, "green": 11, "blue": 10 }, "glInternalFormat": "GL_R11F_G11F_B10F" }, - "ANGLE_FORMAT_R16_FLOAT": { + "R16_FLOAT": { "texFormat": "DXGI_FORMAT_R16_FLOAT", "srvFormat": "DXGI_FORMAT_R16_FLOAT", "rtvFormat": "DXGI_FORMAT_R16_FLOAT", @@ -178,7 +150,7 @@ "bits": { "red": 16 }, "glInternalFormat": "GL_R16F" }, - "ANGLE_FORMAT_R16_SINT": { + "R16_SINT": { "texFormat": "DXGI_FORMAT_R16_SINT", "srvFormat": "DXGI_FORMAT_R16_SINT", "rtvFormat": "DXGI_FORMAT_R16_SINT", @@ -187,7 +159,7 @@ "bits": { "red": 16 }, "glInternalFormat": "GL_R16I" }, - "ANGLE_FORMAT_R16_UINT": { + "R16_UINT": { "texFormat": "DXGI_FORMAT_R16_UINT", "srvFormat": "DXGI_FORMAT_R16_UINT", "rtvFormat": "DXGI_FORMAT_R16_UINT", @@ -196,7 +168,7 @@ "bits": { "red": 16 }, "glInternalFormat": "GL_R16UI" }, - "ANGLE_FORMAT_R32_FLOAT": { + "R32_FLOAT": { "texFormat": "DXGI_FORMAT_R32_FLOAT", "srvFormat": "DXGI_FORMAT_R32_FLOAT", "rtvFormat": "DXGI_FORMAT_R32_FLOAT", @@ -205,7 +177,7 @@ "bits": { "red": 32 }, "glInternalFormat": "GL_R32F" }, - "ANGLE_FORMAT_R32_SINT": { + "R32_SINT": { "texFormat": "DXGI_FORMAT_R32_SINT", "srvFormat": "DXGI_FORMAT_R32_SINT", "rtvFormat": "DXGI_FORMAT_R32_SINT", @@ -214,7 +186,7 @@ "bits": { "red": 32 }, "glInternalFormat": "GL_R32I" }, - "ANGLE_FORMAT_R32_UINT": { + "R32_UINT": { "texFormat": "DXGI_FORMAT_R32_UINT", "srvFormat": "DXGI_FORMAT_R32_UINT", "rtvFormat": "DXGI_FORMAT_R32_UINT", @@ -223,15 +195,7 @@ "bits": { "red": 32 }, "glInternalFormat": "GL_R32UI" }, - "ANGLE_FORMAT_R8_UNORM_NONRENDERABLE": { - "texFormat": "DXGI_FORMAT_R8_UNORM", - "srvFormat": "DXGI_FORMAT_R8_UNORM", - "channels": "r", - "componentType": "unorm", - "bits": { "red": 8 }, - "glInternalFormat": "GL_R8" - }, - "ANGLE_FORMAT_R8_UNORM": { + "R8_UNORM": { "texFormat": "DXGI_FORMAT_R8_UNORM", "srvFormat": "DXGI_FORMAT_R8_UNORM", "rtvFormat": "DXGI_FORMAT_R8_UNORM", @@ -240,7 +204,7 @@ "bits": { "red": 8 }, "glInternalFormat": "GL_R8" }, - "ANGLE_FORMAT_R8_SINT": { + "R8_SINT": { "texFormat": "DXGI_FORMAT_R8_SINT", "srvFormat": "DXGI_FORMAT_R8_SINT", "rtvFormat": "DXGI_FORMAT_R8_SINT", @@ -249,7 +213,7 @@ "bits": { "red": 8 }, "glInternalFormat": "GL_R8I" }, - "ANGLE_FORMAT_R8_UINT": { + "R8_UINT": { "texFormat": "DXGI_FORMAT_R8_UINT", "srvFormat": "DXGI_FORMAT_R8_UINT", "rtvFormat": "DXGI_FORMAT_R8_UINT", @@ -258,7 +222,7 @@ "bits": { "red": 8 }, "glInternalFormat": "GL_R8UI" }, - "ANGLE_FORMAT_R8_SNORM": { + "R8_SNORM": { "texFormat": "DXGI_FORMAT_R8_SNORM", "srvFormat": "DXGI_FORMAT_R8_SNORM", "channels": "r", @@ -266,7 +230,7 @@ "bits": { "red": 8 }, "glInternalFormat": "GL_R8_SNORM" }, - "ANGLE_FORMAT_R16G16_FLOAT": { + "R16G16_FLOAT": { "texFormat": "DXGI_FORMAT_R16G16_FLOAT", "srvFormat": "DXGI_FORMAT_R16G16_FLOAT", "rtvFormat": "DXGI_FORMAT_R16G16_FLOAT", @@ -275,7 +239,7 @@ "bits": { "red": 16, "green": 16 }, "glInternalFormat": "GL_RG16F" }, - "ANGLE_FORMAT_R16G16_SINT": { + "R16G16_SINT": { "texFormat": "DXGI_FORMAT_R16G16_SINT", "srvFormat": "DXGI_FORMAT_R16G16_SINT", "rtvFormat": "DXGI_FORMAT_R16G16_SINT", @@ -284,7 +248,7 @@ "bits": { "red": 16, "green": 16 }, "glInternalFormat": "GL_RG16I" }, - "ANGLE_FORMAT_R16G16_UINT": { + "R16G16_UINT": { "texFormat": "DXGI_FORMAT_R16G16_UINT", "srvFormat": "DXGI_FORMAT_R16G16_UINT", "rtvFormat": "DXGI_FORMAT_R16G16_UINT", @@ -293,7 +257,7 @@ "bits": { "red": 16, "green": 16 }, "glInternalFormat": "GL_RG16UI" }, - "ANGLE_FORMAT_R32G32_FLOAT": { + "R32G32_FLOAT": { "texFormat": "DXGI_FORMAT_R32G32_FLOAT", "srvFormat": "DXGI_FORMAT_R32G32_FLOAT", "rtvFormat": "DXGI_FORMAT_R32G32_FLOAT", @@ -302,7 +266,7 @@ "bits": { "red": 32, "green": 32 }, "glInternalFormat": "GL_RG32F" }, - "ANGLE_FORMAT_R32G32_SINT": { + "R32G32_SINT": { "texFormat": "DXGI_FORMAT_R32G32_SINT", "srvFormat": "DXGI_FORMAT_R32G32_SINT", "rtvFormat": "DXGI_FORMAT_R32G32_SINT", @@ -311,7 +275,7 @@ "bits": { "red": 32, "green": 32 }, "glInternalFormat": "GL_RG32I" }, - "ANGLE_FORMAT_R32G32_UINT": { + "R32G32_UINT": { "texFormat": "DXGI_FORMAT_R32G32_UINT", "srvFormat": "DXGI_FORMAT_R32G32_UINT", "rtvFormat": "DXGI_FORMAT_R32G32_UINT", @@ -320,7 +284,7 @@ "bits": { "red": 32, "green": 32 }, "glInternalFormat": "GL_RG32UI" }, - "ANGLE_FORMAT_R8G8_UNORM": { + "R8G8_UNORM": { "texFormat": "DXGI_FORMAT_R8G8_UNORM", "srvFormat": "DXGI_FORMAT_R8G8_UNORM", "rtvFormat": "DXGI_FORMAT_R8G8_UNORM", @@ -329,15 +293,7 @@ "bits": { "red": 8, "green": 8 }, "glInternalFormat": "GL_RG8" }, - "ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE": { - "texFormat": "DXGI_FORMAT_R8G8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8_UNORM", - "channels": "rg", - "componentType": "unorm", - "bits": { "red": 8, "green": 8 }, - "glInternalFormat": "GL_RG8" - }, - "ANGLE_FORMAT_R8G8_SINT": { + "R8G8_SINT": { "texFormat": "DXGI_FORMAT_R8G8_SINT", "srvFormat": "DXGI_FORMAT_R8G8_SINT", "rtvFormat": "DXGI_FORMAT_R8G8_SINT", @@ -346,7 +302,7 @@ "bits": { "red": 8, "green": 8 }, "glInternalFormat": "GL_RG8I" }, - "ANGLE_FORMAT_R8G8_UINT": { + "R8G8_UINT": { "texFormat": "DXGI_FORMAT_R8G8_UINT", "srvFormat": "DXGI_FORMAT_R8G8_UINT", "rtvFormat": "DXGI_FORMAT_R8G8_UINT", @@ -355,7 +311,7 @@ "bits": { "red": 8, "green": 8 }, "glInternalFormat": "GL_RG8UI" }, - "ANGLE_FORMAT_R8G8_SNORM": { + "R8G8_SNORM": { "texFormat": "DXGI_FORMAT_R8G8_SNORM", "srvFormat": "DXGI_FORMAT_R8G8_SNORM", "channels": "rg", @@ -363,7 +319,7 @@ "bits": { "red": 8, "green": 8 }, "glInternalFormat": "GL_RG8_SNORM" }, - "ANGLE_FORMAT_R10G10B10A2_UNORM": { + "R10G10B10A2_UNORM": { "texFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", "srvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", @@ -372,7 +328,7 @@ "bits": { "red": 10, "green": 10, "blue": 10, "alpha": 2 }, "glInternalFormat": "GL_RGB10_A2" }, - "ANGLE_FORMAT_R10G10B10A2_UINT": { + "R10G10B10A2_UINT": { "texFormat": "DXGI_FORMAT_R10G10B10A2_UINT", "srvFormat": "DXGI_FORMAT_R10G10B10A2_UINT", "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UINT", @@ -381,7 +337,7 @@ "bits": { "red": 10, "green": 10, "blue": 10, "alpha": 2 }, "glInternalFormat": "GL_RGB10_A2UI" }, - "ANGLE_FORMAT_R16G16B16A16_SINT": { + "R16G16B16A16_SINT": { "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT", "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", @@ -390,7 +346,7 @@ "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, "glInternalFormat": "GL_RGBA16I" }, - "ANGLE_FORMAT_R16G16B16A16_UINT": { + "R16G16B16A16_UINT": { "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT", "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", @@ -399,7 +355,7 @@ "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, "glInternalFormat": "GL_RGBA16UI" }, - "ANGLE_FORMAT_R32G32B32A32_SINT": { + "R32G32B32A32_SINT": { "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT", "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", @@ -408,7 +364,7 @@ "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, "glInternalFormat": "GL_RGBA32I" }, - "ANGLE_FORMAT_R32G32B32A32_UINT": { + "R32G32B32A32_UINT": { "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT", "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", @@ -417,27 +373,27 @@ "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, "glInternalFormat": "GL_RGBA32UI" }, - "ANGLE_FORMAT_B5G6R5_UNORM": { + "B5G6R5_UNORM": { "texFormat": "DXGI_FORMAT_B5G6R5_UNORM", "srvFormat": "DXGI_FORMAT_B5G6R5_UNORM", "rtvFormat": "DXGI_FORMAT_B5G6R5_UNORM", "channels": "bgr", "componentType": "unorm", "bits": { "red": 5, "green": 6, "blue": 5 }, - "glInternalFormat": "GL_RGB565", - "channelStruct": "R5G6B5" + "supportTest": "SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" }, - "ANGLE_FORMAT_B5G5R5A1_UNORM": { + "B5G5R5A1_UNORM": { "texFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", "srvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", "rtvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", "channels": "bgra", "componentType": "unorm", "bits": { "red": 5, "green": 5, "blue": 5, "alpha": 1 }, - "glInternalFormat": "GL_RGB5_A1", - "channelStruct": "A1R5G5B5" + "supportTest": "SupportsFormat(DXGI_FORMAT_B5G5R5A1_UNORM, deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" }, - "ANGLE_FORMAT_R8G8B8A8_SINT": { + "R8G8B8A8_SINT": { "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT", "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", @@ -446,7 +402,7 @@ "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, "glInternalFormat": "GL_RGBA8I" }, - "ANGLE_FORMAT_R8G8B8A8_UINT": { + "R8G8B8A8_UINT": { "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT", "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", @@ -455,7 +411,7 @@ "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, "glInternalFormat": "GL_RGBA8UI" }, - "ANGLE_FORMAT_R8G8B8A8_SNORM": { + "R8G8B8A8_SNORM": { "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", "channels": "rgba", @@ -463,26 +419,24 @@ "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, "glInternalFormat": "GL_RGBA8_SNORM" }, - "ANGLE_FORMAT_R9G9B9E5_SHAREDEXP": { + "R9G9B9E5_SHAREDEXP": { "texFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", "srvFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", "channels": "rgb", "componentType": "float", - "bits": { "red": 9, "green": 9, "blue": 9, "shared": 5 }, - "glInternalFormat": "GL_RGB9_E5", - "channelStruct": "R9G9B9E5" + "bits": { "red": 9, "green": 9, "blue": 9, "shared": 5 } }, - "ANGLE_FORMAT_B4G4R4A4_UNORM": { + "B4G4R4A4_UNORM": { "texFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", "srvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", "rtvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", "channels": "bgra", "componentType": "unorm", "bits": { "red": 4, "green": 4, "blue": 4, "alpha": 4 }, - "glInternalFormat": "GL_RGBA4", - "channelStruct": "A4R4G4B4" + "supportTest": "SupportsFormat(DXGI_FORMAT_B4G4R4A4_UNORM, deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" }, - "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB": { + "R8G8B8A8_UNORM_SRGB": { "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", @@ -491,31 +445,25 @@ "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, "glInternalFormat": "GL_SRGB8_ALPHA8" }, - "ANGLE_FORMAT_X24_TYPELESS_G8_UINT": { - "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "srvFormat": "DXGI_FORMAT_X24_TYPELESS_G8_UINT", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "channels": "ds", - "bits": { "depth": 24, "stencil": 8 }, - "glInternalFormat": "GL_DEPTH24_STENCIL8_OES" - }, - "ANGLE_FORMAT_R16_UNORM": { + "R16_UNORM": { "texFormat": "DXGI_FORMAT_R16_UNORM", "srvFormat": "DXGI_FORMAT_R16_UNORM", "rtvFormat": "DXGI_FORMAT_R16_UNORM", "channels": "r", "componentType": "unorm", - "bits": { "red": 16 } + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16_EXT" }, - "ANGLE_FORMAT_R16G16_UNORM": { + "R16G16_UNORM": { "texFormat": "DXGI_FORMAT_R16G16_UNORM", "srvFormat": "DXGI_FORMAT_R16G16_UNORM", "rtvFormat": "DXGI_FORMAT_R16G16_UNORM", "channels": "rg", "componentType": "unorm", - "bits": { "red": 16, "green": 16 } + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16_EXT" }, - "ANGLE_FORMAT_R16_SNORM": { + "R16_SNORM": { "texFormat": "DXGI_FORMAT_R16_SNORM", "srvFormat": "DXGI_FORMAT_R16_SNORM", "channels": "r", @@ -523,7 +471,7 @@ "bits": { "red": 16 }, "glInternalFormat": "GL_R16_SNORM_EXT" }, - "ANGLE_FORMAT_R16G16_SNORM": { + "R16G16_SNORM": { "texFormat": "DXGI_FORMAT_R16G16_SNORM", "srvFormat": "DXGI_FORMAT_R16G16_SNORM", "channels": "rg", @@ -531,7 +479,7 @@ "bits": { "red": 16, "green": 16 }, "glInternalFormat": "GL_RG16_SNORM_EXT" }, - "ANGLE_FORMAT_R16G16B16A16_SNORM": { + "R16G16B16A16_SNORM": { "texFormat": "DXGI_FORMAT_R16G16B16A16_SNORM", "srvFormat": "DXGI_FORMAT_R16G16B16A16_SNORM", "channels": "rgba", diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json index 5ef0787ce80..9b2e8d9db66 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json @@ -1,156 +1,74 @@ { - "GL_ALPHA": { - "OnlyFL10Plus": "ANGLE_FORMAT_A8_UNORM", - "OnlyFL9_3": "ANGLE_FORMAT_R8G8B8A8_UNORM" - }, - "GL_ALPHA16F_EXT": "ANGLE_FORMAT_R16G16B16A16_FLOAT", - "GL_ALPHA32F_EXT": "ANGLE_FORMAT_R32G32B32A32_FLOAT", - "GL_ALPHA8_EXT": { - "OnlyFL10Plus": "ANGLE_FORMAT_A8_UNORM", - "OnlyFL9_3": "ANGLE_FORMAT_R8G8B8A8_UNORM" - }, - "GL_BGR5_A1_ANGLEX": "ANGLE_FORMAT_B8G8R8A8_UNORM", - "GL_BGRA4_ANGLEX": "ANGLE_FORMAT_B8G8R8A8_UNORM", - "GL_BGRA8_EXT": "ANGLE_FORMAT_B8G8R8A8_UNORM", - "GL_BGRA_EXT": "ANGLE_FORMAT_B8G8R8A8_UNORM", - "GL_COMPRESSED_R11_EAC": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8_UNORM_NONRENDERABLE" - }, - "GL_COMPRESSED_RG11_EAC": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE" - }, - "GL_COMPRESSED_RGB8_ETC2": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE" - }, - "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE" - }, - "GL_COMPRESSED_RGBA8_ETC2_EAC": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE" - }, - "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": "ANGLE_FORMAT_BC1_UNORM", - "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": "ANGLE_FORMAT_BC2_UNORM", - "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": "ANGLE_FORMAT_BC3_UNORM", - "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": "ANGLE_FORMAT_BC1_UNORM", - "GL_COMPRESSED_SIGNED_R11_EAC": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8_SNORM_NONRENDERABLE" - }, - "GL_COMPRESSED_SIGNED_RG11_EAC": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE" - }, - "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE" - }, - "GL_COMPRESSED_SRGB8_ETC2": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE" - }, - "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": { - "OnlyFL10Plus": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE" - }, - "GL_DEPTH24_STENCIL8": { - "OnlyFL10Plus": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10", - "OnlyFL9_3": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3" - }, - "GL_DEPTH32F_STENCIL8": { - "OnlyFL10Plus": "ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10", - "OnlyFL9_3": "ANGLE_FORMAT_NONE" - }, - "GL_DEPTH_COMPONENT16": { - "OnlyFL10Plus": "ANGLE_FORMAT_D16_UNORM_FL10", - "OnlyFL9_3": "ANGLE_FORMAT_D16_UNORM_FL9_3" - }, - "GL_DEPTH_COMPONENT24": { - "OnlyFL10Plus": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10", - "OnlyFL9_3": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3" - }, - "GL_DEPTH_COMPONENT32F": { - "OnlyFL10Plus": "ANGLE_FORMAT_D32_FLOAT", - "OnlyFL9_3": "ANGLE_FORMAT_NONE" - }, - "GL_DEPTH_COMPONENT32_OES": { - "OnlyFL10Plus": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10" - }, - "GL_ETC1_RGB8_OES": "ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE", - "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": "ANGLE_FORMAT_BC1_UNORM", - "GL_LUMINANCE": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_LUMINANCE16F_EXT": "ANGLE_FORMAT_R16G16B16A16_FLOAT", - "GL_LUMINANCE32F_EXT": "ANGLE_FORMAT_R32G32B32A32_FLOAT", - "GL_LUMINANCE8_ALPHA8_EXT": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_LUMINANCE8_EXT": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_LUMINANCE_ALPHA": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_LUMINANCE_ALPHA16F_EXT": "ANGLE_FORMAT_R16G16B16A16_FLOAT", - "GL_LUMINANCE_ALPHA32F_EXT": "ANGLE_FORMAT_R32G32B32A32_FLOAT", - "GL_NONE": "ANGLE_FORMAT_NONE", - "GL_R11F_G11F_B10F": "ANGLE_FORMAT_R11G11B10_FLOAT", - "GL_R16F": "ANGLE_FORMAT_R16_FLOAT", - "GL_R16I": "ANGLE_FORMAT_R16_SINT", - "GL_R16UI": "ANGLE_FORMAT_R16_UINT", - "GL_R32F": "ANGLE_FORMAT_R32_FLOAT", - "GL_R32I": "ANGLE_FORMAT_R32_SINT", - "GL_R32UI": "ANGLE_FORMAT_R32_UINT", - "GL_R8": "ANGLE_FORMAT_R8_UNORM", - "GL_R8I": "ANGLE_FORMAT_R8_SINT", - "GL_R8UI": "ANGLE_FORMAT_R8_UINT", - "GL_R8_SNORM": "ANGLE_FORMAT_R8_SNORM", - "GL_RG16F": "ANGLE_FORMAT_R16G16_FLOAT", - "GL_RG16I": "ANGLE_FORMAT_R16G16_SINT", - "GL_RG16UI": "ANGLE_FORMAT_R16G16_UINT", - "GL_RG32F": "ANGLE_FORMAT_R32G32_FLOAT", - "GL_RG32I": "ANGLE_FORMAT_R32G32_SINT", - "GL_RG32UI": "ANGLE_FORMAT_R32G32_UINT", - "GL_RG8": "ANGLE_FORMAT_R8G8_UNORM", - "GL_RG8I": "ANGLE_FORMAT_R8G8_SINT", - "GL_RG8UI": "ANGLE_FORMAT_R8G8_UINT", - "GL_RG8_SNORM": "ANGLE_FORMAT_R8G8_SNORM", - "GL_RGB": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_RGB10_A2": "ANGLE_FORMAT_R10G10B10A2_UNORM", - "GL_RGB10_A2UI": "ANGLE_FORMAT_R10G10B10A2_UINT", - "GL_RGB16F": "ANGLE_FORMAT_R16G16B16A16_FLOAT", - "GL_RGB16I": "ANGLE_FORMAT_R16G16B16A16_SINT", - "GL_RGB16UI": "ANGLE_FORMAT_R16G16B16A16_UINT", - "GL_RGB32F": "ANGLE_FORMAT_R32G32B32A32_FLOAT", - "GL_RGB32I": "ANGLE_FORMAT_R32G32B32A32_SINT", - "GL_RGB32UI": "ANGLE_FORMAT_R32G32B32A32_UINT", - "GL_RGB565": { - "SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,false>": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,true>": "ANGLE_FORMAT_B5G6R5_UNORM" - }, - "GL_RGB5_A1": { - "SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,false>": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,true>": "ANGLE_FORMAT_B5G5R5A1_UNORM" - }, - "GL_RGB8": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_RGB8I": "ANGLE_FORMAT_R8G8B8A8_SINT", - "GL_RGB8UI": "ANGLE_FORMAT_R8G8B8A8_UINT", - "GL_RGB8_SNORM": "ANGLE_FORMAT_R8G8B8A8_SNORM", - "GL_RGB9_E5": "ANGLE_FORMAT_R9G9B9E5_SHAREDEXP", - "GL_RGBA": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_RGBA16F": "ANGLE_FORMAT_R16G16B16A16_FLOAT", - "GL_RGBA16I": "ANGLE_FORMAT_R16G16B16A16_SINT", - "GL_RGBA16UI": "ANGLE_FORMAT_R16G16B16A16_UINT", - "GL_RGBA32F": "ANGLE_FORMAT_R32G32B32A32_FLOAT", - "GL_RGBA32I": "ANGLE_FORMAT_R32G32B32A32_SINT", - "GL_RGBA32UI": "ANGLE_FORMAT_R32G32B32A32_UINT", - "GL_RGBA4": { - "SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,false>": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,true>": "ANGLE_FORMAT_B4G4R4A4_UNORM" - }, - "GL_RGBA8": "ANGLE_FORMAT_R8G8B8A8_UNORM", - "GL_RGBA8I": "ANGLE_FORMAT_R8G8B8A8_SINT", - "GL_RGBA8UI": "ANGLE_FORMAT_R8G8B8A8_UINT", - "GL_RGBA8_SNORM": "ANGLE_FORMAT_R8G8B8A8_SNORM", - "GL_SRGB8": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE", - "GL_SRGB8_ALPHA8": "ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB", - "GL_STENCIL_INDEX8": { - "OnlyFL10Plus": "ANGLE_FORMAT_X24_TYPELESS_G8_UINT", - "OnlyFL9_3": "ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3" - }, - "GL_R16_EXT": "ANGLE_FORMAT_R16_UNORM", - "GL_RG16_EXT": "ANGLE_FORMAT_R16G16_UNORM", - "GL_RGB16_EXT": "ANGLE_FORMAT_R16G16B16A16_UNORM", - "GL_RGBA16_EXT": "ANGLE_FORMAT_R16G16B16A16_UNORM", - "GL_R16_SNORM_EXT": "ANGLE_FORMAT_R16_SNORM", - "GL_RG16_SNORM_EXT": "ANGLE_FORMAT_R16G16_SNORM", - "GL_RGB16_SNORM_EXT": "ANGLE_FORMAT_R16G16B16A16_SNORM", - "GL_RGBA16_SNORM_EXT": "ANGLE_FORMAT_R16G16B16A16_SNORM" + "GL_ALPHA16F_EXT": "R16G16B16A16_FLOAT", + "GL_ALPHA32F_EXT": "R32G32B32A32_FLOAT", + "GL_BGR5_A1_ANGLEX": "B8G8R8A8_UNORM", + "GL_BGRA4_ANGLEX": "B8G8R8A8_UNORM", + "GL_COMPRESSED_R11_EAC": "R8_UNORM", + "GL_COMPRESSED_RG11_EAC": "R8G8_UNORM", + "GL_COMPRESSED_RGB8_ETC2": "R8G8B8A8_UNORM", + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM", + "GL_COMPRESSED_RGBA8_ETC2_EAC": "R8G8B8A8_UNORM", + "GL_COMPRESSED_RGBA_ASTC_4x4_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_5x4_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_5x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_6x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_6x6_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_8x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_8x6_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_8x8_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x6_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x8_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x10_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_12x10_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_12x12_KHR": "NONE", + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": "BC1_RGB_UNORM_BLOCK", + "GL_COMPRESSED_SIGNED_R11_EAC": "R8_SNORM", + "GL_COMPRESSED_SIGNED_RG11_EAC": "R8G8_SNORM", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": "R8G8B8A8_UNORM_SRGB", + "GL_COMPRESSED_SRGB8_ETC2": "R8G8B8A8_UNORM_SRGB", + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM_SRGB", + "GL_DEPTH_COMPONENT24": "D24_UNORM_S8_UINT", + "GL_DEPTH_COMPONENT32_OES": "D24_UNORM_S8_UINT", + "GL_ETC1_RGB8_OES": "R8G8B8A8_UNORM", + "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": "BC1_RGB_UNORM_BLOCK", + "GL_LUMINANCE16F_EXT": "R16G16B16A16_FLOAT", + "GL_LUMINANCE32F_EXT": "R32G32B32A32_FLOAT", + "GL_LUMINANCE8_ALPHA8_EXT": "R8G8B8A8_UNORM", + "GL_LUMINANCE8_EXT": "R8G8B8A8_UNORM", + "GL_LUMINANCE_ALPHA16F_EXT": "R16G16B16A16_FLOAT", + "GL_LUMINANCE_ALPHA32F_EXT": "R32G32B32A32_FLOAT", + "GL_RGB": "R8G8B8A8_UNORM", + "GL_RGB16F": "R16G16B16A16_FLOAT", + "GL_RGB16I": "R16G16B16A16_SINT", + "GL_RGB16UI": "R16G16B16A16_UINT", + "GL_RGB565": "B5G6R5_UNORM", + "GL_RGB5_A1": "B5G5R5A1_UNORM", + "GL_RGB8": "R8G8B8A8_UNORM", + "GL_RGB8I": "R8G8B8A8_SINT", + "GL_RGB8UI": "R8G8B8A8_UINT", + "GL_RGB8_SNORM": "R8G8B8A8_SNORM", + "GL_RGBA4": "B4G4R4A4_UNORM", + "GL_SRGB8": "R8G8B8A8_UNORM_SRGB", + "GL_STENCIL_INDEX8": "D24_UNORM_S8_UINT", + "GL_RGB16_EXT": "R16G16B16A16_UNORM", + "GL_RGBA16_EXT": "R16G16B16A16_UNORM", + "GL_RGB16_SNORM_EXT": "R16G16B16A16_SNORM", + "GL_RGB32F": "R32G32B32A32_FLOAT", + "GL_RGB32I": "R32G32B32A32_SINT", + "GL_RGB32UI": "R32G32B32A32_UINT" } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp new file mode 100644 index 00000000000..6697a117792 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp @@ -0,0 +1,56 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Helper routines for the D3D11 texture format table. + +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +#include "libANGLE/renderer/load_functions_table.h" + +namespace rx +{ + +namespace d3d11 +{ + +Format::Format() + : internalFormat(GL_NONE), + format(angle::Format::Get(angle::Format::ID::NONE)), + texFormat(DXGI_FORMAT_UNKNOWN), + srvFormat(DXGI_FORMAT_UNKNOWN), + rtvFormat(DXGI_FORMAT_UNKNOWN), + dsvFormat(DXGI_FORMAT_UNKNOWN), + blitSRVFormat(DXGI_FORMAT_UNKNOWN), + swizzle(*this), + dataInitializerFunction(nullptr) +{ +} + +Format::Format(GLenum internalFormat, + angle::Format::ID formatID, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + GLenum swizzleFormat, + InitializeTextureDataFunction internalFormatInitializer, + const Renderer11DeviceCaps &deviceCaps) + : internalFormat(internalFormat), + format(angle::Format::Get(formatID)), + texFormat(texFormat), + srvFormat(srvFormat), + rtvFormat(rtvFormat), + dsvFormat(dsvFormat), + blitSRVFormat(blitSRVFormat), + swizzle(swizzleFormat == internalFormat ? *this : Format::Get(swizzleFormat, deviceCaps)), + dataInitializerFunction(internalFormatInitializer), + loadFunctions(GetLoadFunctionsMap(internalFormat, formatID)) +{ +} + +} // namespace d3d11 + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h index 95d104f455e..8e05a2eb871 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h @@ -14,9 +14,9 @@ #include "common/angleutils.h" #include "common/platform.h" +#include "libANGLE/renderer/Format.h" #include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" -#include "libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h" namespace rx { @@ -26,39 +26,28 @@ struct Renderer11DeviceCaps; namespace d3d11 { -struct LoadImageFunctionInfo +// For sized GL internal formats, there are several possible corresponding D3D11 formats depending +// on device capabilities. +// This structure allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and +// DSVs given a GL internal format. +struct Format final : angle::NonCopyable { - LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {} - LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion) - : loadFunction(loadFunction), requiresConversion(requiresConversion) - { - } - - LoadImageFunction loadFunction; - bool requiresConversion; -}; - -struct ANGLEFormatSet -{ - ANGLEFormatSet(); - ANGLEFormatSet(ANGLEFormat format, - GLenum glInternalFormat, - DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, - DXGI_FORMAT rtvFormat, - DXGI_FORMAT dsvFormat, - DXGI_FORMAT blitSRVFormat, - ANGLEFormat swizzleFormat, - MipGenerationFunction mipGenerationFunction, - ColorReadFunction colorReadFunction); - ANGLEFormatSet(const ANGLEFormatSet &) = default; - ANGLEFormatSet &operator=(const ANGLEFormatSet &) = default; - - ANGLEFormat format; - - // The closest matching GL internal format for the DXGI formats this format uses. Note that this - // may be a different internal format than the one this ANGLE format is used for. - GLenum glInternalFormat; + Format(); + Format(GLenum internalFormat, + angle::Format::ID formatID, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + GLenum swizzleFormat, + InitializeTextureDataFunction internalFormatInitializer, + const Renderer11DeviceCaps &deviceCaps); + + static const Format &Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps); + + GLenum internalFormat; + const angle::Format &format; DXGI_FORMAT texFormat; DXGI_FORMAT srvFormat; @@ -67,32 +56,13 @@ struct ANGLEFormatSet DXGI_FORMAT blitSRVFormat; - ANGLEFormat swizzleFormat; - - MipGenerationFunction mipGenerationFunction; - ColorReadFunction colorReadFunction; -}; - -struct TextureFormat : public angle::NonCopyable -{ - TextureFormat(GLenum internalFormat, - const ANGLEFormat angleFormat, - InitializeTextureDataFunction internalFormatInitializer); - - const ANGLEFormatSet *formatSet; - const ANGLEFormatSet *swizzleFormatSet; + const Format &swizzle; InitializeTextureDataFunction dataInitializerFunction; - typedef std::map<GLenum, LoadImageFunctionInfo> LoadFunctionMap; LoadFunctionMap loadFunctions; }; -const ANGLEFormatSet &GetANGLEFormatSet(ANGLEFormat angleFormat); - -const TextureFormat &GetTextureFormatInfo(GLenum internalformat, - const Renderer11DeviceCaps &renderer11DeviceCaps); - } // namespace d3d11 } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp index b559db3df53..d5eab7bc159 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp @@ -11,12 +11,15 @@ #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" -#include "libANGLE/renderer/copyimage.h" +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "libANGLE/renderer/d3d/generatemip.h" -#include "libANGLE/renderer/d3d/loadimage.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h" + +using namespace angle; namespace rx { @@ -24,1962 +27,1916 @@ namespace rx namespace d3d11 { -namespace -{ - -typedef bool (*FormatSupportFunction)(const Renderer11DeviceCaps &); - -bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) -{ - return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); -} - -bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) -{ - return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); -} - -template <DXGI_FORMAT format, bool requireSupport> -bool SupportsFormat(const Renderer11DeviceCaps &deviceCaps) -{ - // Must support texture, SRV and RTV support - UINT mustSupport = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | - D3D11_FORMAT_SUPPORT_RENDER_TARGET; - - if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel) > 2) - { - mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; - } - - bool fullSupport = false; - if (format == DXGI_FORMAT_B5G6R5_UNORM) - { - // All hardware that supports DXGI_FORMAT_B5G6R5_UNORM should support autogen mipmaps, but - // check anyway. - mustSupport |= D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; - fullSupport = ((deviceCaps.B5G6R5support & mustSupport) == mustSupport); - } - else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) - { - fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport); - } - else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) - { - fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport); - } - else - { - UNREACHABLE(); - return false; - } - - // This 'SupportsFormat' function is used by individual entries in the D3D11 Format Map below, - // which maps GL formats to DXGI formats. - if (requireSupport) - { - // This means that ANGLE would like to use the entry in the map if the inputted DXGI format - // *IS* supported. - // e.g. the entry might map GL_RGB5_A1 to DXGI_FORMAT_B5G5R5A1, which should only be used if - // DXGI_FORMAT_B5G5R5A1 is supported. - // In this case, we should only return 'true' if the format *IS* supported. - return fullSupport; - } - else - { - // This means that ANGLE would like to use the entry in the map if the inputted DXGI format - // *ISN'T* supported. - // This might be a fallback entry. e.g. for ANGLE to use DXGI_FORMAT_R8G8B8A8_UNORM if - // DXGI_FORMAT_B5G5R5A1 isn't supported. - // In this case, we should only return 'true' if the format *ISN'T* supported. - return !fullSupport; - } -} - -// End Format Support Functions -} // namespace - -ANGLEFormatSet::ANGLEFormatSet() - : format(ANGLE_FORMAT_NONE), - glInternalFormat(GL_NONE), - texFormat(DXGI_FORMAT_UNKNOWN), - srvFormat(DXGI_FORMAT_UNKNOWN), - rtvFormat(DXGI_FORMAT_UNKNOWN), - dsvFormat(DXGI_FORMAT_UNKNOWN), - blitSRVFormat(DXGI_FORMAT_UNKNOWN), - swizzleFormat(ANGLE_FORMAT_NONE), - mipGenerationFunction(nullptr), - colorReadFunction(nullptr) -{ -} - -// For sized GL internal formats, there are several possible corresponding D3D11 formats depending -// on device capabilities. -// This function allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and -// DSVs given a GL internal format. -TextureFormat::TextureFormat(GLenum internalFormat, - const ANGLEFormat angleFormat, - InitializeTextureDataFunction internalFormatInitializer) - : dataInitializerFunction(internalFormatInitializer) -{ - formatSet = &GetANGLEFormatSet(angleFormat); - swizzleFormatSet = &GetANGLEFormatSet(formatSet->swizzleFormat); - - // Gather all the load functions for this internal format - loadFunctions = GetLoadFunctionsMap(internalFormat, formatSet->texFormat); - - ASSERT(loadFunctions.size() != 0 || internalFormat == GL_NONE); -} - -ANGLEFormatSet::ANGLEFormatSet(ANGLEFormat format, - GLenum glInternalFormat, - DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, - DXGI_FORMAT rtvFormat, - DXGI_FORMAT dsvFormat, - DXGI_FORMAT blitSRVFormat, - ANGLEFormat swizzleFormat, - MipGenerationFunction mipGenerationFunction, - ColorReadFunction colorReadFunction) - : format(format), - glInternalFormat(glInternalFormat), - texFormat(texFormat), - srvFormat(srvFormat), - rtvFormat(rtvFormat), - dsvFormat(dsvFormat), - blitSRVFormat(blitSRVFormat), - swizzleFormat(swizzleFormat), - mipGenerationFunction(mipGenerationFunction), - colorReadFunction(colorReadFunction) -{ -} - -const ANGLEFormatSet &GetANGLEFormatSet(ANGLEFormat angleFormat) -{ - // clang-format off - switch (angleFormat) - { - case ANGLE_FORMAT_A8_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_A8_UNORM, - GL_ALPHA8_EXT, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_A8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<A8>, - ReadColor<A8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_B4G4R4A4_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B4G4R4A4_UNORM, - GL_RGBA4, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_B4G4R4A4_UNORM, - ANGLE_FORMAT_B4G4R4A4_UNORM, - GenerateMip<A4R4G4B4>, - ReadColor<A4R4G4B4, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_B5G5R5A1_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B5G5R5A1_UNORM, - GL_RGB5_A1, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_B5G5R5A1_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<A1R5G5B5>, - ReadColor<A1R5G5B5, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_B5G6R5_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B5G6R5_UNORM, - GL_RGB565, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_B5G6R5_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R5G6B5>, - ReadColor<R5G6B5, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_B8G8R8A8_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_B8G8R8A8_UNORM, - GL_BGRA8_EXT, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_B8G8R8A8_UNORM, - ANGLE_FORMAT_B8G8R8A8_UNORM, - GenerateMip<B8G8R8A8>, - ReadColor<B8G8R8A8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_BC1_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_BC1_UNORM, - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_BC1_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_BC2_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_BC2_UNORM, - GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, - DXGI_FORMAT_BC2_UNORM, - DXGI_FORMAT_BC2_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_BC2_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_BC3_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_BC3_UNORM, - GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, - DXGI_FORMAT_BC3_UNORM, - DXGI_FORMAT_BC3_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_BC3_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_D16_UNORM_FL10: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D16_UNORM_FL10, - GL_DEPTH_COMPONENT16, - DXGI_FORMAT_R16_TYPELESS, - DXGI_FORMAT_R16_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D16_UNORM, - DXGI_FORMAT_R16_UNORM, - ANGLE_FORMAT_R16G16B16A16_UNORM, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_D16_UNORM_FL9_3: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D16_UNORM_FL9_3, - GL_DEPTH_COMPONENT16, - DXGI_FORMAT_D16_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D16_UNORM, - DXGI_FORMAT_UNKNOWN, - ANGLE_FORMAT_R16G16B16A16_UNORM, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, - GL_DEPTH24_STENCIL8_OES, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, - GL_DEPTH24_STENCIL8_OES, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_UNKNOWN, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_D32_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D32_FLOAT, - GL_DEPTH_COMPONENT32F, - DXGI_FORMAT_R32_TYPELESS, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D32_FLOAT, - DXGI_FORMAT_R32_FLOAT, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10, - GL_DEPTH32F_STENCIL8, - DXGI_FORMAT_R32G8X24_TYPELESS, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_NONE: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_NONE, - GL_NONE, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - ANGLE_FORMAT_NONE, - nullptr, - nullptr); - return formatInfo; - } - case ANGLE_FORMAT_R10G10B10A2_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R10G10B10A2_UINT, - GL_RGB10_A2UI, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R10G10B10A2_UINT, - ANGLE_FORMAT_R16G16B16A16_UINT, - GenerateMip<R10G10B10A2>, - ReadColor<R10G10B10A2, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R10G10B10A2_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R10G10B10A2_UNORM, - GL_RGB10_A2, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R10G10B10A2_UNORM, - ANGLE_FORMAT_R16G16B16A16_UNORM, - GenerateMip<R10G10B10A2>, - ReadColor<R10G10B10A2, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R11G11B10_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R11G11B10_FLOAT, - GL_R11F_G11F_B10F, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R11G11B10_FLOAT, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - GenerateMip<R11G11B10F>, - ReadColor<R11G11B10F, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16B16A16_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_FLOAT, - GL_RGBA16F, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16B16A16_FLOAT, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - GenerateMip<R16G16B16A16F>, - ReadColor<R16G16B16A16F, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16B16A16_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_SINT, - GL_RGBA16I, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16B16A16_SINT, - ANGLE_FORMAT_R16G16B16A16_SINT, - GenerateMip<R16G16B16A16S>, - ReadColor<R16G16B16A16S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16B16A16_SNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_SNORM, - GL_RGBA16_SNORM_EXT, - DXGI_FORMAT_R16G16B16A16_SNORM, - DXGI_FORMAT_R16G16B16A16_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16B16A16_SNORM, - ANGLE_FORMAT_R16G16B16A16_SNORM, - GenerateMip<R16G16B16A16S>, - ReadColor<R16G16B16A16S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16B16A16_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_UINT, - GL_RGBA16UI, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16B16A16_UINT, - ANGLE_FORMAT_R16G16B16A16_UINT, - GenerateMip<R16G16B16A16>, - ReadColor<R16G16B16A16, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16B16A16_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16B16A16_UNORM, - GL_NONE, - DXGI_FORMAT_R16G16B16A16_UNORM, - DXGI_FORMAT_R16G16B16A16_UNORM, - DXGI_FORMAT_R16G16B16A16_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16B16A16_UNORM, - ANGLE_FORMAT_R16G16B16A16_UNORM, - GenerateMip<R16G16B16A16>, - ReadColor<R16G16B16A16, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_FLOAT, - GL_RG16F, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16_FLOAT, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - GenerateMip<R16G16F>, - ReadColor<R16G16F, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_SINT, - GL_RG16I, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16_SINT, - ANGLE_FORMAT_R16G16B16A16_SINT, - GenerateMip<R16G16S>, - ReadColor<R16G16S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16_SNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_SNORM, - GL_RG16_SNORM_EXT, - DXGI_FORMAT_R16G16_SNORM, - DXGI_FORMAT_R16G16_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16_SNORM, - ANGLE_FORMAT_R16G16B16A16_SNORM, - GenerateMip<R16G16S>, - ReadColor<R16G16S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_UINT, - GL_RG16UI, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16_UINT, - ANGLE_FORMAT_R16G16B16A16_UINT, - GenerateMip<R16G16>, - ReadColor<R16G16, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R16G16_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16G16_UNORM, - GL_NONE, - DXGI_FORMAT_R16G16_UNORM, - DXGI_FORMAT_R16G16_UNORM, - DXGI_FORMAT_R16G16_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16G16_UNORM, - ANGLE_FORMAT_R16G16B16A16_UNORM, - GenerateMip<R16G16>, - ReadColor<R16G16, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_FLOAT, - GL_R16F, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16_FLOAT, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - GenerateMip<R16F>, - ReadColor<R16F, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_SINT, - GL_R16I, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16_SINT, - ANGLE_FORMAT_R16G16B16A16_SINT, - GenerateMip<R16S>, - ReadColor<R16S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R16_SNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_SNORM, - GL_R16_SNORM_EXT, - DXGI_FORMAT_R16_SNORM, - DXGI_FORMAT_R16_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16_SNORM, - ANGLE_FORMAT_R16G16B16A16_SNORM, - GenerateMip<R16S>, - ReadColor<R16S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R16_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_UINT, - GL_R16UI, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16_UINT, - ANGLE_FORMAT_R16G16B16A16_UINT, - GenerateMip<R16>, - ReadColor<R16, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R16_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R16_UNORM, - GL_NONE, - DXGI_FORMAT_R16_UNORM, - DXGI_FORMAT_R16_UNORM, - DXGI_FORMAT_R16_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R16_UNORM, - ANGLE_FORMAT_R16G16B16A16_UNORM, - GenerateMip<R16>, - ReadColor<R16, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R32G32B32A32_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32B32A32_FLOAT, - GL_RGBA32F, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32G32B32A32_FLOAT, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - GenerateMip<R32G32B32A32F>, - ReadColor<R32G32B32A32F, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R32G32B32A32_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32B32A32_SINT, - GL_RGBA32I, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32G32B32A32_SINT, - ANGLE_FORMAT_R32G32B32A32_SINT, - GenerateMip<R32G32B32A32S>, - ReadColor<R32G32B32A32S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R32G32B32A32_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32B32A32_UINT, - GL_RGBA32UI, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32G32B32A32_UINT, - ANGLE_FORMAT_R32G32B32A32_UINT, - GenerateMip<R32G32B32A32>, - ReadColor<R32G32B32A32, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R32G32_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32_FLOAT, - GL_RG32F, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32G32_FLOAT, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - GenerateMip<R32G32F>, - ReadColor<R32G32F, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R32G32_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32_SINT, - GL_RG32I, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32G32_SINT, - ANGLE_FORMAT_R32G32B32A32_SINT, - GenerateMip<R32G32S>, - ReadColor<R32G32S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R32G32_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32G32_UINT, - GL_RG32UI, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32G32_UINT, - ANGLE_FORMAT_R32G32B32A32_UINT, - GenerateMip<R32G32>, - ReadColor<R32G32, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R32_FLOAT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32_FLOAT, - GL_R32F, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32_FLOAT, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - GenerateMip<R32F>, - ReadColor<R32F, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R32_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32_SINT, - GL_R32I, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32_SINT, - ANGLE_FORMAT_R32G32B32A32_SINT, - GenerateMip<R32S>, - ReadColor<R32S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R32_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R32_UINT, - GL_R32UI, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32_UINT, - ANGLE_FORMAT_R32G32B32A32_UINT, - GenerateMip<R32>, - ReadColor<R32, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8B8A8_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_SINT, - GL_RGBA8I, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8B8A8_SINT, - ANGLE_FORMAT_R8G8B8A8_SINT, - GenerateMip<R8G8B8A8S>, - ReadColor<R8G8B8A8S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8B8A8_SNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_SNORM, - GL_RGBA8_SNORM, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8B8A8_SNORM, - ANGLE_FORMAT_R8G8B8A8_SNORM, - GenerateMip<R8G8B8A8S>, - ReadColor<R8G8B8A8S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8B8A8_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UINT, - GL_RGBA8UI, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8B8A8_UINT, - ANGLE_FORMAT_R8G8B8A8_UINT, - GenerateMip<R8G8B8A8>, - ReadColor<R8G8B8A8, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8B8A8_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM, - GL_RGBA8, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8B8A8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R8G8B8A8>, - ReadColor<R8G8B8A8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, - GL_RGBA8, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8B8A8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R8G8B8A8>, - ReadColor<R8G8B8A8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, - GL_SRGB8_ALPHA8, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, - GenerateMip<R8G8B8A8>, - ReadColor<R8G8B8A8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, - GL_SRGB8_ALPHA8, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R8G8B8A8>, - ReadColor<R8G8B8A8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_SINT, - GL_RG8I, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8_SINT, - ANGLE_FORMAT_R8G8B8A8_SINT, - GenerateMip<R8G8S>, - ReadColor<R8G8S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8_SNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_SNORM, - GL_RG8_SNORM, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8_SNORM, - ANGLE_FORMAT_R8G8B8A8_SNORM, - GenerateMip<R8G8S>, - ReadColor<R8G8S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE, - GL_RG8_SNORM, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8_SNORM, - ANGLE_FORMAT_R8G8B8A8_SNORM, - GenerateMip<R8G8S>, - ReadColor<R8G8S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_UINT, - GL_RG8UI, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8_UINT, - ANGLE_FORMAT_R8G8B8A8_UINT, - GenerateMip<R8G8>, - ReadColor<R8G8, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_UNORM, - GL_RG8, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R8G8>, - ReadColor<R8G8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE, - GL_RG8, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8G8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R8G8>, - ReadColor<R8G8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8_SINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_SINT, - GL_R8I, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8_SINT, - ANGLE_FORMAT_R8G8B8A8_SINT, - GenerateMip<R8S>, - ReadColor<R8S, GLint>); - return formatInfo; - } - case ANGLE_FORMAT_R8_SNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_SNORM, - GL_R8_SNORM, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8_SNORM, - ANGLE_FORMAT_R8G8B8A8_SNORM, - GenerateMip<R8S>, - ReadColor<R8S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8_SNORM_NONRENDERABLE: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_SNORM_NONRENDERABLE, - GL_R8_SNORM, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8_SNORM, - ANGLE_FORMAT_R8G8B8A8_SNORM, - GenerateMip<R8S>, - ReadColor<R8S, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_UINT, - GL_R8UI, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8_UINT, - ANGLE_FORMAT_R8G8B8A8_UINT, - GenerateMip<R8>, - ReadColor<R8, GLuint>); - return formatInfo; - } - case ANGLE_FORMAT_R8_UNORM: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_UNORM, - GL_R8, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R8>, - ReadColor<R8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R8_UNORM_NONRENDERABLE: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R8_UNORM_NONRENDERABLE, - GL_R8, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM, - GenerateMip<R8>, - ReadColor<R8, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_R9G9B9E5_SHAREDEXP: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_R9G9B9E5_SHAREDEXP, - GL_RGB9_E5, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - GenerateMip<R9G9B9E5>, - ReadColor<R9G9B9E5, GLfloat>); - return formatInfo; - } - case ANGLE_FORMAT_X24_TYPELESS_G8_UINT: - { - static const ANGLEFormatSet formatInfo(ANGLE_FORMAT_X24_TYPELESS_G8_UINT, - GL_DEPTH24_STENCIL8_OES, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_X24_TYPELESS_G8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_X24_TYPELESS_G8_UINT, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr, - nullptr); - return formatInfo; - } - - default: - break; - } - // clang-format on - - UNREACHABLE(); - static const ANGLEFormatSet defaultInfo; - return defaultInfo; -} - -const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, - const Renderer11DeviceCaps &renderer11DeviceCaps) +// static +const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps) { // clang-format off switch (internalFormat) { - case GL_ALPHA: - { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_A8_UNORM, - nullptr); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; - } - else - { - break; - } - } case GL_ALPHA16F_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_ALPHA16F_EXT, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + nullptr, + deviceCaps); + return info; } case GL_ALPHA32F_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_ALPHA32F_EXT, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } case GL_ALPHA8_EXT: { - if (OnlyFL10Plus(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_ALPHA8_EXT, + angle::Format::ID::A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } - else if (OnlyFL9_3(renderer11DeviceCaps)) + else { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_ALPHA8_EXT, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; + } + } + case GL_BGR565_ANGLEX: + { + if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)) + { + static const Format info(GL_BGR565_ANGLEX, + angle::Format::ID::B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_BGR565_ANGLEX, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } } case GL_BGR5_A1_ANGLEX: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_B8G8R8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_BGR5_A1_ANGLEX, + angle::Format::ID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + GL_BGRA8_EXT, + nullptr, + deviceCaps); + return info; } case GL_BGRA4_ANGLEX: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_B8G8R8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_BGRA4_ANGLEX, + angle::Format::ID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + GL_BGRA8_EXT, + nullptr, + deviceCaps); + return info; } case GL_BGRA8_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_B8G8R8A8_UNORM, - nullptr); - return textureFormat; - } - case GL_BGRA_EXT: - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_B8G8R8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_BGRA8_EXT, + angle::Format::ID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + GL_BGRA8_EXT, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_R11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8_UNORM_NONRENDERABLE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_R11_EAC, + angle::Format::ID::R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_RG11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_RG11_EAC, + angle::Format::ID::R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_RGB8_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_RGB8_ETC2, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_COMPRESSED_RGBA8_ETC2_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_RGBA8_ETC2_EAC, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + { + static const Format info(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_BC1_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + angle::Format::ID::BC1_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_BC2_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + angle::Format::ID::BC2_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC2_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_BC3_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + angle::Format::ID::BC3_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC3_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_BC1_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + angle::Format::ID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_SIGNED_R11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8_SNORM_NONRENDERABLE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_SIGNED_R11_EAC, + angle::Format::ID::R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SNORM, + GL_RGBA8_SNORM, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_SIGNED_RG11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_SIGNED_RG11_EAC, + angle::Format::ID::R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SNORM, + GL_RGBA8_SNORM, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + { + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + nullptr, + deviceCaps); + return info; } case GL_COMPRESSED_SRGB8_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_SRGB8_ETC2, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + nullptr, + deviceCaps); + return info; } case GL_DEPTH24_STENCIL8: { - if (OnlyFL10Plus(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, - nullptr); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, - nullptr); - return textureFormat; + static const Format info(GL_DEPTH24_STENCIL8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_DEPTH24_STENCIL8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } } case GL_DEPTH32F_STENCIL8: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10, - nullptr); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_NONE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_DEPTH32F_STENCIL8, + angle::Format::ID::D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R32G8X24_TYPELESS, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } case GL_DEPTH_COMPONENT16: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D16_UNORM_FL10, - nullptr); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D16_UNORM_FL9_3, - nullptr); - return textureFormat; + static const Format info(GL_DEPTH_COMPONENT16, + angle::Format::ID::D16_UNORM, + DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_R16_UNORM, + GL_RGBA16_EXT, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_DEPTH_COMPONENT16, + angle::Format::ID::D16_UNORM, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + GL_RGBA16_EXT, + nullptr, + deviceCaps); + return info; } } case GL_DEPTH_COMPONENT24: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, - nullptr); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, - nullptr); - return textureFormat; + static const Format info(GL_DEPTH_COMPONENT24, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_DEPTH_COMPONENT24, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } } case GL_DEPTH_COMPONENT32F: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D32_FLOAT, - nullptr); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_NONE, - nullptr); - return textureFormat; - } - else - { - break; - } + static const Format info(GL_DEPTH_COMPONENT32F, + angle::Format::ID::D32_FLOAT, + DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } case GL_DEPTH_COMPONENT32_OES: { - if (OnlyFL10Plus(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, - nullptr); - return textureFormat; + static const Format info(GL_DEPTH_COMPONENT32_OES, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_DEPTH_COMPONENT32_OES, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } } case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_BC1_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, + angle::Format::ID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_ETC1_RGB8_OES: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; - } - case GL_LUMINANCE: - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; + static const Format info(GL_ETC1_RGB8_OES, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_LUMINANCE16F_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>); - return textureFormat; + static const Format info(GL_LUMINANCE16F_EXT, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>, + deviceCaps); + return info; } case GL_LUMINANCE32F_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>); - return textureFormat; + static const Format info(GL_LUMINANCE32F_EXT, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>, + deviceCaps); + return info; } case GL_LUMINANCE8_ALPHA8_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_LUMINANCE8_ALPHA8_EXT, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_LUMINANCE8_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; - } - case GL_LUMINANCE_ALPHA: - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_LUMINANCE8_EXT, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_LUMINANCE_ALPHA16F_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_LUMINANCE_ALPHA16F_EXT, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + nullptr, + deviceCaps); + return info; } case GL_LUMINANCE_ALPHA32F_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_LUMINANCE_ALPHA32F_EXT, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } case GL_NONE: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_NONE, - nullptr); - return textureFormat; + static const Format info(GL_NONE, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr, + deviceCaps); + return info; } case GL_R11F_G11F_B10F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R11G11B10_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_R11F_G11F_B10F, + angle::Format::ID::R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R11G11B10_FLOAT, + GL_RGBA16F_EXT, + nullptr, + deviceCaps); + return info; } case GL_R16F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_R16F, + angle::Format::ID::R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_FLOAT, + GL_RGBA16F_EXT, + nullptr, + deviceCaps); + return info; } case GL_R16I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16_SINT, - nullptr); - return textureFormat; + static const Format info(GL_R16I, + angle::Format::ID::R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SINT, + GL_RGBA16I, + nullptr, + deviceCaps); + return info; } case GL_R16UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16_UINT, - nullptr); - return textureFormat; + static const Format info(GL_R16UI, + angle::Format::ID::R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UINT, + GL_RGBA16I, + nullptr, + deviceCaps); + return info; } case GL_R16_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_R16_EXT, + angle::Format::ID::R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UNORM, + GL_RGBA16_EXT, + nullptr, + deviceCaps); + return info; } case GL_R16_SNORM_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16_SNORM, - nullptr); - return textureFormat; + static const Format info(GL_R16_SNORM_EXT, + angle::Format::ID::R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SNORM, + GL_RGBA16_SNORM_EXT, + nullptr, + deviceCaps); + return info; } case GL_R32F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_R32F, + angle::Format::ID::R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_FLOAT, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } case GL_R32I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32_SINT, - nullptr); - return textureFormat; + static const Format info(GL_R32I, + angle::Format::ID::R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_SINT, + GL_RGBA32I, + nullptr, + deviceCaps); + return info; } case GL_R32UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32_UINT, - nullptr); - return textureFormat; + static const Format info(GL_R32UI, + angle::Format::ID::R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_UINT, + GL_RGBA32I, + nullptr, + deviceCaps); + return info; } case GL_R8: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_R8, + angle::Format::ID::R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_R8I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8_SINT, - nullptr); - return textureFormat; + static const Format info(GL_R8I, + angle::Format::ID::R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SINT, + GL_RGBA8I, + nullptr, + deviceCaps); + return info; } case GL_R8UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8_UINT, - nullptr); - return textureFormat; + static const Format info(GL_R8UI, + angle::Format::ID::R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UINT, + GL_RGBA8I, + nullptr, + deviceCaps); + return info; } case GL_R8_SNORM: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8_SNORM, - nullptr); - return textureFormat; + static const Format info(GL_R8_SNORM, + angle::Format::ID::R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SNORM, + GL_RGBA8_SNORM, + nullptr, + deviceCaps); + return info; } case GL_RG16F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_RG16F, + angle::Format::ID::R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_FLOAT, + GL_RGBA16F_EXT, + nullptr, + deviceCaps); + return info; } case GL_RG16I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16_SINT, - nullptr); - return textureFormat; + static const Format info(GL_RG16I, + angle::Format::ID::R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SINT, + GL_RGBA16I, + nullptr, + deviceCaps); + return info; } case GL_RG16UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16_UINT, - nullptr); - return textureFormat; + static const Format info(GL_RG16UI, + angle::Format::ID::R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UINT, + GL_RGBA16I, + nullptr, + deviceCaps); + return info; } case GL_RG16_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RG16_EXT, + angle::Format::ID::R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UNORM, + GL_RGBA16_EXT, + nullptr, + deviceCaps); + return info; } case GL_RG16_SNORM_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16_SNORM, - nullptr); - return textureFormat; + static const Format info(GL_RG16_SNORM_EXT, + angle::Format::ID::R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SNORM, + GL_RGBA16_SNORM_EXT, + nullptr, + deviceCaps); + return info; } case GL_RG32F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_RG32F, + angle::Format::ID::R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_FLOAT, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } case GL_RG32I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32_SINT, - nullptr); - return textureFormat; + static const Format info(GL_RG32I, + angle::Format::ID::R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_SINT, + GL_RGBA32I, + nullptr, + deviceCaps); + return info; } case GL_RG32UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32_UINT, - nullptr); - return textureFormat; + static const Format info(GL_RG32UI, + angle::Format::ID::R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_UINT, + GL_RGBA32I, + nullptr, + deviceCaps); + return info; } case GL_RG8: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RG8, + angle::Format::ID::R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_RG8I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8_SINT, - nullptr); - return textureFormat; + static const Format info(GL_RG8I, + angle::Format::ID::R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SINT, + GL_RGBA8I, + nullptr, + deviceCaps); + return info; } case GL_RG8UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8_UINT, - nullptr); - return textureFormat; + static const Format info(GL_RG8UI, + angle::Format::ID::R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UINT, + GL_RGBA8I, + nullptr, + deviceCaps); + return info; } case GL_RG8_SNORM: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8_SNORM, - nullptr); - return textureFormat; + static const Format info(GL_RG8_SNORM, + angle::Format::ID::R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SNORM, + GL_RGBA8_SNORM, + nullptr, + deviceCaps); + return info; } case GL_RGB: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; + static const Format info(GL_RGB, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_RGB10_A2: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R10G10B10A2_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGB10_A2, + angle::Format::ID::R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + GL_RGBA16_EXT, + nullptr, + deviceCaps); + return info; } case GL_RGB10_A2UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R10G10B10A2_UINT, - nullptr); - return textureFormat; + static const Format info(GL_RGB10_A2UI, + angle::Format::ID::R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UINT, + GL_RGBA16I, + nullptr, + deviceCaps); + return info; } case GL_RGB16F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>); - return textureFormat; + static const Format info(GL_RGB16F, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>, + deviceCaps); + return info; } case GL_RGB16I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_SINT, - Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>); - return textureFormat; + static const Format info(GL_RGB16I, + angle::Format::ID::R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SINT, + GL_RGBA16I, + Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>, + deviceCaps); + return info; } case GL_RGB16UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_UINT, - Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>); - return textureFormat; + static const Format info(GL_RGB16UI, + angle::Format::ID::R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UINT, + GL_RGBA16UI, + Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>, + deviceCaps); + return info; } case GL_RGB16_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_UNORM, - Initialize4ComponentData<GLubyte, 0x0000, 0x0000, 0x0000, 0xFFFF>); - return textureFormat; + static const Format info(GL_RGB16_EXT, + angle::Format::ID::R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + GL_RGBA16_EXT, + Initialize4ComponentData<GLubyte, 0x0000, 0x0000, 0x0000, 0xFFFF>, + deviceCaps); + return info; } case GL_RGB16_SNORM_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_SNORM, - Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x7FFF>); - return textureFormat; + static const Format info(GL_RGB16_SNORM_EXT, + angle::Format::ID::R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SNORM, + GL_RGBA16_SNORM_EXT, + Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x7FFF>, + deviceCaps); + return info; } case GL_RGB32F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>); - return textureFormat; + static const Format info(GL_RGB32F, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>, + deviceCaps); + return info; } case GL_RGB32I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_SINT, - Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>); - return textureFormat; + static const Format info(GL_RGB32I, + angle::Format::ID::R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_SINT, + GL_RGBA32I, + Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>, + deviceCaps); + return info; } case GL_RGB32UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_UINT, - Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>); - return textureFormat; + static const Format info(GL_RGB32UI, + angle::Format::ID::R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_UINT, + GL_RGBA32UI, + Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>, + deviceCaps); + return info; } case GL_RGB565: { - if (SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,false>(renderer11DeviceCaps)) + if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; - } - else if (SupportsFormat<DXGI_FORMAT_B5G6R5_UNORM,true>(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_B5G6R5_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGB565, + angle::Format::ID::B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_RGB565, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } } case GL_RGB5_A1: { - if (SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,false>(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; - } - else if (SupportsFormat<DXGI_FORMAT_B5G5R5A1_UNORM,true>(renderer11DeviceCaps)) + if (SupportsFormat(DXGI_FORMAT_B5G5R5A1_UNORM, deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_B5G5R5A1_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGB5_A1, + angle::Format::ID::B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G5R5A1_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_RGB5_A1, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } } case GL_RGB8: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; + static const Format info(GL_RGB8, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_RGB8I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_SINT, - Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>); - return textureFormat; + static const Format info(GL_RGB8I, + angle::Format::ID::R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SINT, + GL_RGBA8I, + Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>, + deviceCaps); + return info; } case GL_RGB8UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UINT, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>); - return textureFormat; + static const Format info(GL_RGB8UI, + angle::Format::ID::R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UINT, + GL_RGBA8UI, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>, + deviceCaps); + return info; } case GL_RGB8_SNORM: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_SNORM, - Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x7F>); - return textureFormat; + static const Format info(GL_RGB8_SNORM, + angle::Format::ID::R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SNORM, + GL_RGBA8_SNORM, + Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x7F>, + deviceCaps); + return info; } case GL_RGB9_E5: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R9G9B9E5_SHAREDEXP, - nullptr); - return textureFormat; + static const Format info(GL_RGB9_E5, + angle::Format::ID::R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + GL_RGBA16F_EXT, + nullptr, + deviceCaps); + return info; } case GL_RGBA: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGBA, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_RGBA16F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA16F, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + nullptr, + deviceCaps); + return info; } case GL_RGBA16I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_SINT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA16I, + angle::Format::ID::R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SINT, + GL_RGBA16I, + nullptr, + deviceCaps); + return info; } case GL_RGBA16UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_UINT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA16UI, + angle::Format::ID::R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UINT, + GL_RGBA16UI, + nullptr, + deviceCaps); + return info; } case GL_RGBA16_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGBA16_EXT, + angle::Format::ID::R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + GL_RGBA16_EXT, + nullptr, + deviceCaps); + return info; } case GL_RGBA16_SNORM_EXT: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R16G16B16A16_SNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGBA16_SNORM_EXT, + angle::Format::ID::R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SNORM, + GL_RGBA16_SNORM_EXT, + nullptr, + deviceCaps); + return info; } case GL_RGBA32F: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA32F, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } case GL_RGBA32I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_SINT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA32I, + angle::Format::ID::R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_SINT, + GL_RGBA32I, + nullptr, + deviceCaps); + return info; } case GL_RGBA32UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R32G32B32A32_UINT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA32UI, + angle::Format::ID::R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_UINT, + GL_RGBA32UI, + nullptr, + deviceCaps); + return info; } case GL_RGBA4: { - if (SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,false>(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; - } - else if (SupportsFormat<DXGI_FORMAT_B4G4R4A4_UNORM,true>(renderer11DeviceCaps)) + if (SupportsFormat(DXGI_FORMAT_B4G4R4A4_UNORM, deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_B4G4R4A4_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGBA4, + angle::Format::ID::B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B4G4R4A4_UNORM, + GL_RGBA4, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_RGBA4, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } } case GL_RGBA8: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGBA8, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr, + deviceCaps); + return info; } case GL_RGBA8I: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_SINT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA8I, + angle::Format::ID::R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SINT, + GL_RGBA8I, + nullptr, + deviceCaps); + return info; } case GL_RGBA8UI: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UINT, - nullptr); - return textureFormat; + static const Format info(GL_RGBA8UI, + angle::Format::ID::R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UINT, + GL_RGBA8UI, + nullptr, + deviceCaps); + return info; } case GL_RGBA8_SNORM: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_SNORM, - nullptr); - return textureFormat; + static const Format info(GL_RGBA8_SNORM, + angle::Format::ID::R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SNORM, + GL_RGBA8_SNORM, + nullptr, + deviceCaps); + return info; } case GL_SRGB8: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, - Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>); - return textureFormat; + static const Format info(GL_SRGB8, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>, + deviceCaps); + return info; } case GL_SRGB8_ALPHA8: { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, - nullptr); - return textureFormat; + static const Format info(GL_SRGB8_ALPHA8, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + nullptr, + deviceCaps); + return info; } case GL_STENCIL_INDEX8: { - if (OnlyFL10Plus(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_X24_TYPELESS_G8_UINT, - nullptr); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat(internalFormat, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, - nullptr); - return textureFormat; + static const Format info(GL_STENCIL_INDEX8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } else { - break; + static const Format info(GL_STENCIL_INDEX8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr, + deviceCaps); + return info; } } @@ -1988,9 +1945,10 @@ const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, } // clang-format on - static const TextureFormat defaultInfo(GL_NONE, ANGLE_FORMAT_NONE, nullptr); + UNREACHABLE(); + static const Format defaultInfo; return defaultInfo; -} // GetTextureFormatInfo +} } // namespace d3d11 diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h deleted file mode 100644 index 9259577f4fd..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h +++ /dev/null @@ -1,84 +0,0 @@ -// GENERATED FILE - DO NOT EDIT. -// Generated by gen_texture_format_table.py using data from texture_format_data.json -// -// Copyright 2016 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -namespace rx -{ - -namespace d3d11 -{ - -enum ANGLEFormat -{ - ANGLE_FORMAT_A8_UNORM, - ANGLE_FORMAT_B4G4R4A4_UNORM, - ANGLE_FORMAT_B5G5R5A1_UNORM, - ANGLE_FORMAT_B5G6R5_UNORM, - ANGLE_FORMAT_B8G8R8A8_UNORM, - ANGLE_FORMAT_BC1_UNORM, - ANGLE_FORMAT_BC2_UNORM, - ANGLE_FORMAT_BC3_UNORM, - ANGLE_FORMAT_D16_UNORM_FL10, - ANGLE_FORMAT_D16_UNORM_FL9_3, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL10, - ANGLE_FORMAT_D24_UNORM_S8_UINT_FL9_3, - ANGLE_FORMAT_D32_FLOAT, - ANGLE_FORMAT_D32_FLOAT_S8X24_UINT_FL10, - ANGLE_FORMAT_NONE, - ANGLE_FORMAT_R10G10B10A2_UINT, - ANGLE_FORMAT_R10G10B10A2_UNORM, - ANGLE_FORMAT_R11G11B10_FLOAT, - ANGLE_FORMAT_R16G16B16A16_FLOAT, - ANGLE_FORMAT_R16G16B16A16_SINT, - ANGLE_FORMAT_R16G16B16A16_SNORM, - ANGLE_FORMAT_R16G16B16A16_UINT, - ANGLE_FORMAT_R16G16B16A16_UNORM, - ANGLE_FORMAT_R16G16_FLOAT, - ANGLE_FORMAT_R16G16_SINT, - ANGLE_FORMAT_R16G16_SNORM, - ANGLE_FORMAT_R16G16_UINT, - ANGLE_FORMAT_R16G16_UNORM, - ANGLE_FORMAT_R16_FLOAT, - ANGLE_FORMAT_R16_SINT, - ANGLE_FORMAT_R16_SNORM, - ANGLE_FORMAT_R16_UINT, - ANGLE_FORMAT_R16_UNORM, - ANGLE_FORMAT_R32G32B32A32_FLOAT, - ANGLE_FORMAT_R32G32B32A32_SINT, - ANGLE_FORMAT_R32G32B32A32_UINT, - ANGLE_FORMAT_R32G32_FLOAT, - ANGLE_FORMAT_R32G32_SINT, - ANGLE_FORMAT_R32G32_UINT, - ANGLE_FORMAT_R32_FLOAT, - ANGLE_FORMAT_R32_SINT, - ANGLE_FORMAT_R32_UINT, - ANGLE_FORMAT_R8G8B8A8_SINT, - ANGLE_FORMAT_R8G8B8A8_SNORM, - ANGLE_FORMAT_R8G8B8A8_UINT, - ANGLE_FORMAT_R8G8B8A8_UNORM, - ANGLE_FORMAT_R8G8B8A8_UNORM_NONRENDERABLE, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB, - ANGLE_FORMAT_R8G8B8A8_UNORM_SRGB_NONRENDERABLE, - ANGLE_FORMAT_R8G8_SINT, - ANGLE_FORMAT_R8G8_SNORM, - ANGLE_FORMAT_R8G8_SNORM_NONRENDERABLE, - ANGLE_FORMAT_R8G8_UINT, - ANGLE_FORMAT_R8G8_UNORM, - ANGLE_FORMAT_R8G8_UNORM_NONRENDERABLE, - ANGLE_FORMAT_R8_SINT, - ANGLE_FORMAT_R8_SNORM, - ANGLE_FORMAT_R8_SNORM_NONRENDERABLE, - ANGLE_FORMAT_R8_UINT, - ANGLE_FORMAT_R8_UNORM, - ANGLE_FORMAT_R8_UNORM_NONRENDERABLE, - ANGLE_FORMAT_R9G9B9E5_SHAREDEXP, - ANGLE_FORMAT_X24_TYPELESS_G8_UINT -}; - -} // namespace d3d11 - -} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h new file mode 100644 index 00000000000..bffea6af920 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h @@ -0,0 +1,77 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Helper routines for the D3D11 texture format table. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ + +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +namespace d3d11 +{ + +using FormatSupportFunction = bool (*)(const Renderer11DeviceCaps &); + +inline bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); +} + +inline bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); +} + +inline bool SupportsFormat(DXGI_FORMAT format, const Renderer11DeviceCaps &deviceCaps) +{ + // Must support texture, SRV and RTV support + UINT mustSupport = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE | + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | + D3D11_FORMAT_SUPPORT_RENDER_TARGET; + + if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel) > 2) + { + mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + } + + bool fullSupport = false; + if (format == DXGI_FORMAT_B5G6R5_UNORM) + { + // All hardware that supports DXGI_FORMAT_B5G6R5_UNORM should support autogen mipmaps, but + // check anyway. + mustSupport |= D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; + fullSupport = ((deviceCaps.B5G6R5support & mustSupport) == mustSupport); + } + else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) + { + fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport); + } + else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) + { + fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport); + } + else + { + UNREACHABLE(); + return false; + } + + // This means that ANGLE would like to use the entry in the map if the inputted DXGI format + // *IS* supported. + // e.g. the entry might map GL_RGB5_A1 to DXGI_FORMAT_B5G5R5A1, which should only be used if + // DXGI_FORMAT_B5G5R5A1 is supported. + // In this case, we should only return 'true' if the format *IS* supported. + return fullSupport; +} + +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp index fa00d60f68f..0211e6887a5 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp @@ -167,17 +167,6 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf()); if (SUCCEEDED(result)) { - -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On - // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed - // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations. - if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED) - { - mSupportsSwapChainResize = false; - } -#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - result = newSwapChain.CopyTo(swapChain); } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp index 0ee0d8325b9..63ee649f066 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp @@ -22,7 +22,7 @@ Buffer9::~Buffer9() mSize = 0; } -gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) +gl::Error Buffer9::setData(GLenum /*target*/, const void *data, size_t size, GLenum usage) { if (size > mMemory.size()) { @@ -51,7 +51,7 @@ gl::Error Buffer9::getData(const uint8_t **outData) return gl::Error(GL_NO_ERROR); } -gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer9::setSubData(GLenum /*target*/, const void *data, size_t size, size_t offset) { if (offset + size > mMemory.size()) { diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h index 219f8a6584c..9dd08b5100a 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h @@ -29,13 +29,16 @@ class Buffer9 : public BufferD3D gl::Error getData(const uint8_t **outData) override; // BufferImpl implementation - virtual gl::Error setData(const void* data, size_t size, GLenum usage); - virtual gl::Error setSubData(const void* data, size_t size, size_t offset); - virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual gl::Error map(GLenum access, GLvoid **mapPtr); - virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); - virtual gl::Error unmap(GLboolean *result); - virtual gl::Error markTransformFeedbackUsage(); + gl::Error setData(GLenum target, const void *data, size_t size, GLenum usage) override; + gl::Error setSubData(GLenum target, const void *data, size_t size, size_t offset) override; + gl::Error copySubData(BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + gl::Error map(GLenum access, GLvoid **mapPtr) override; + gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override; + gl::Error unmap(GLboolean *result) override; + gl::Error markTransformFeedbackUsage() override; private: MemoryBuffer mMemory; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp index 5c5358a9d49..1c90fffa1bc 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp @@ -16,7 +16,6 @@ #include "libANGLE/renderer/d3d/RenderbufferD3D.h" #include "libANGLE/renderer/d3d/SamplerD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" #include "libANGLE/renderer/d3d/d3d9/Buffer9.h" #include "libANGLE/renderer/d3d/d3d9/Fence9.h" #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" @@ -49,7 +48,7 @@ CompilerImpl *Context9::createCompiler() ShaderImpl *Context9::createShader(const gl::ShaderState &data) { - return new ShaderD3D(data); + return new ShaderD3D(data, mRenderer->getWorkarounds()); } ProgramImpl *Context9::createProgram(const gl::ProgramState &data) @@ -110,9 +109,10 @@ FenceSyncImpl *Context9::createFenceSync() return nullptr; } -TransformFeedbackImpl *Context9::createTransformFeedback() +TransformFeedbackImpl *Context9::createTransformFeedback(const gl::TransformFeedbackState &state) { - return new TransformFeedbackD3D(); + UNREACHABLE(); + return nullptr; } SamplerImpl *Context9::createSampler() @@ -178,24 +178,9 @@ gl::Error Context9::drawRangeElements(GLenum mode, return mRenderer->genericDrawElements(this, mode, count, type, indices, 0, indexRange); } -void Context9::notifyDeviceLost() -{ - mRenderer->notifyDeviceLost(); -} - -bool Context9::isDeviceLost() const -{ - return mRenderer->isDeviceLost(); -} - -bool Context9::testDeviceLost() -{ - return mRenderer->testDeviceLost(); -} - -bool Context9::testDeviceResettable() +GLenum Context9::getResetStatus() { - return mRenderer->testDeviceResettable(); + return mRenderer->getResetStatus(); } std::string Context9::getVendorString() const diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h index aa788e16edb..7e3492f9a03 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h @@ -50,7 +50,8 @@ class Context9 : public ContextImpl FenceSyncImpl *createFenceSync() override; // Transform Feedback creation - TransformFeedbackImpl *createTransformFeedback() override; + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; // Sampler object creation SamplerImpl *createSampler() override; @@ -88,11 +89,8 @@ class Context9 : public ContextImpl const GLvoid *indices, const gl::IndexRange &indexRange) override; - // TODO(jmadill): Investigate proper impl methods for this. - void notifyDeviceLost() override; - bool isDeviceLost() const override; - bool testDeviceLost() override; - bool testDeviceResettable() override; + // Device loss + GLenum getResetStatus() override; // Vendor and description strings. std::string getVendorString() const override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp index 9687cc96d69..9286d9b0da3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp @@ -192,9 +192,7 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, int inputPitch = lock.Pitch; const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); - const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat); gl::FormatType formatType(format, type); - ColorReadFunction colorReadFunction = d3dFormatInfo.colorReadFunction; // TODO(jmadill): Maybe we can avoid a copy of pack parameters here? PackPixelsParams packParams; @@ -207,8 +205,7 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, packParams.outputPitch = static_cast<GLuint>(outputPitch); packParams.pack = pack; - PackPixels(packParams, sourceFormatInfo, d3dFormatInfo.fastCopyFunctions, colorReadFunction, - inputPitch, source, pixels); + PackPixels(packParams, *d3dFormatInfo.info, inputPitch, source, pixels); systemSurface->UnlockRect(); SafeRelease(systemSurface); @@ -407,7 +404,7 @@ GLenum Framebuffer9::getRenderTargetImplementationFormat(RenderTargetD3D *render { RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTarget); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(renderTarget9->getD3DFormat()); - return d3dFormatInfo.internalFormat; + return d3dFormatInfo.info->glInternalFormat; } } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp index 081e3ac14a6..3c14b43a52b 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp @@ -61,7 +61,7 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); - ASSERT(d3dFormatInfo.mipGenerationFunction != NULL); + ASSERT(d3dFormatInfo.info->mipGenerationFunction != NULL); D3DLOCKED_RECT sourceLocked = {0}; result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); @@ -85,8 +85,8 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(sourceData && destData); - d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, - destData, destLocked.Pitch, 0); + d3dFormatInfo.info->mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, + sourceLocked.Pitch, 0, destData, destLocked.Pitch, 0); destSurface->UnlockRect(); sourceSurface->UnlockRect(); @@ -525,9 +525,8 @@ gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) GLsizei inputRowPitch = 0; ANGLE_TRY_RESULT(formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0), inputRowPitch); GLsizei inputDepthPitch = 0; - ANGLE_TRY_RESULT( - formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0), - inputDepthPitch); + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, 0, inputDepthPitch), + inputDepthPitch); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp index 419bff1f63e..3e54c27f437 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp @@ -130,7 +130,8 @@ GLsizei SurfaceRenderTarget9::getDepth() const GLenum SurfaceRenderTarget9::getInternalFormat() const { - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); + return (mDepth ? mSwapChain->getDepthBufferInternalFormat() + : mSwapChain->getRenderTargetInternalFormat()); } GLsizei SurfaceRenderTarget9::getSamples() const diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp index 3e817eebcce..61da36177e5 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -47,7 +47,6 @@ #include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" #include "libANGLE/State.h" #include "libANGLE/Surface.h" #include "libANGLE/Texture.h" @@ -1790,17 +1789,26 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, RenderTarget9 *colorRenderTarget9 = GetAs<RenderTarget9>(colorRenderTarget); ASSERT(colorRenderTarget9); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(colorBuffer->getInternalFormat()); + const gl::InternalFormat &formatInfo = *colorBuffer->getFormat().info; const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(colorRenderTarget9->getD3DFormat()); - color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), - gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), - gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), - gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue)); - - if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + color = + D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) + ? 1.0f + : clearParams.colorFClearValue.alpha), + gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) + ? 0.0f + : clearParams.colorFClearValue.red), + gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) + ? 0.0f + : clearParams.colorFClearValue.green), + gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) + ? 0.0f + : clearParams.colorFClearValue.blue)); + + if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || - (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { needMaskedColorClear = true; @@ -2037,19 +2045,7 @@ void Renderer9::releaseDeviceResources() bool Renderer9::testDeviceLost() { HRESULT status = getDeviceStatusCode(); - bool isLost = FAILED(status); - - if (isLost) - { - // ensure we note the device loss -- - // we'll probably get this done again by notifyDeviceLost - // but best to remember it! - // Note that we don't want to clear the device loss status here - // -- this needs to be done by resetDevice - mDeviceLost = true; - } - - return isLost; + return FAILED(status); } HRESULT Renderer9::getDeviceStatusCode() @@ -2152,8 +2148,6 @@ bool Renderer9::resetDevice() initializeDevice(); } - mDeviceLost = false; - return true; } @@ -2331,6 +2325,21 @@ gl::Error Renderer9::copyImage2DArray(const gl::Framebuffer *framebuffer, const return gl::Error(GL_INVALID_OPERATION); } +gl::Error Renderer9::copyTexture(const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) { const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format); @@ -2642,9 +2651,10 @@ TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) return new TextureStorage9_2D(this, swapChain9); } -TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage) +TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) { - return new TextureStorage9_EGLImage(this, eglImage); + return new TextureStorage9_EGLImage(this, eglImage, GetAs<RenderTarget9>(renderTargetD3D)); } TextureStorage *Renderer9::createTextureStorageExternal( @@ -2887,4 +2897,9 @@ FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::FramebufferState return new Framebuffer9(state, this); } +gl::Version Renderer9::getMaxSupportedESVersion() const +{ + return gl::Version(2, 0); +} + } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h index 8172fa17caf..fb8d8fa2150 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h @@ -69,7 +69,7 @@ class Renderer9 : public RendererD3D virtual ~Renderer9(); egl::Error initialize() override; - virtual bool resetDevice(); + bool resetDevice() override; egl::ConfigSet generateConfigs() override; void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; @@ -101,8 +101,11 @@ class Renderer9 : public RendererD3D gl::Error createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader); HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); + gl::Error setSamplerState(gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler) override; + gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) override; gl::Error setUniformBuffers(const gl::ContextState &data, const std::vector<GLint> &vertexUniformBuffers, @@ -145,7 +148,7 @@ class Renderer9 : public RendererD3D const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer); - virtual void markAllStateDirty(); + void markAllStateDirty(); // lost device bool testDeviceLost() override; @@ -165,7 +168,7 @@ class Renderer9 : public RendererD3D bool getShareHandleSupport() const; - virtual int getMajorShaderModel() const; + int getMajorShaderModel() const override; int getMinorShaderModel() const override; std::string getShaderModelSuffix() const override; @@ -198,6 +201,17 @@ class Renderer9 : public RendererD3D TextureStorage *storage, GLint level) override; + gl::Error copyTexture(const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + // RenderTarget creation gl::Error createRenderTarget(int width, int height, @@ -227,8 +241,9 @@ class Renderer9 : public RendererD3D gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; gl::Error generateMipmapUsingD3D(TextureStorage *storage, const gl::TextureState &textureState) override; - virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain); - TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; + TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override; + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) override; TextureStorage *createTextureStorageExternal( egl::Stream *stream, const egl::Stream::GLTextureDescription &desc) override; @@ -266,14 +281,13 @@ class Renderer9 : public RendererD3D const egl::AttributeMap &attribs) override; // Buffer-to-texture and Texture-to-buffer copies - virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); - - // EXT_debug_marker - void insertEventMarker(GLsizei length, const char *marker); - void pushGroupMarker(GLsizei length, const char *marker); - void popGroupMarker(); + bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override; + gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) override; // D3D9-renderer specific methods gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); @@ -316,6 +330,8 @@ class Renderer9 : public RendererD3D DebugAnnotator9 *getAnnotator() { return &mAnnotator; } + gl::Version getMaxSupportedESVersion() const override; + protected: gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp index d9afddb32ed..5fb675ddb3f 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp @@ -833,14 +833,12 @@ void StateManager9::setColorMask(const gl::Framebuffer *framebuffer, { // Set the color mask - const gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + const auto *attachment = framebuffer->getFirstColorbuffer(); + const auto &format = attachment ? attachment->getFormat() : gl::Format::Invalid(); DWORD colorMask = gl_d3d9::ConvertColorMask( - formatInfo.redBits > 0 && red, formatInfo.greenBits > 0 && green, - formatInfo.blueBits > 0 && blue, formatInfo.alphaBits > 0 && alpha); + format.info->redBits > 0 && red, format.info->greenBits > 0 && green, + format.info->blueBits > 0 && blue, format.info->alphaBits > 0 && alpha); // Apparently some ATI cards have a bug where a draw with a zero color write mask can cause // later draws to have incorrect results. Instead, set a nonzero color write mask but modify the diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp index 4484fccfe18..b61809050ee 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp @@ -335,7 +335,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) // On Windows 8 systems, IDirect3DSwapChain9::Present sometimes returns 0x88760873 when the windows is // in the process of entering/exiting fullscreen. This code doesn't seem to have any documentation. The // device appears to be ok after emitting this error so simply return a failure to swap. - if (result == 0x88760873) + if (result == static_cast<HRESULT>(0x88760873)) { return EGL_BAD_MATCH; } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp index b28d5076b5a..fd792752aec 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp @@ -107,7 +107,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai mTexture = surfaceTexture; mMipLevels = surfaceTexture->GetLevelCount(); - mInternalFormat = swapchain->GetRenderTargetInternalFormat(); + mInternalFormat = swapchain->getRenderTargetInternalFormat(); D3DSURFACE_DESC surfaceDesc; surfaceTexture->GetLevelDesc(0, &surfaceDesc); @@ -305,14 +305,11 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) return gl::Error(GL_NO_ERROR); } -TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image) +TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, + EGLImageD3D *image, + RenderTarget9 *renderTarget9) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET), mImage(image) { - RenderTargetD3D *renderTargetD3D = nullptr; - mImage->getRenderTarget(&renderTargetD3D); - - RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D); - mInternalFormat = renderTarget9->getInternalFormat(); mTextureFormat = renderTarget9->getD3DFormat(); mTextureWidth = renderTarget9->getWidth(); @@ -434,7 +431,7 @@ TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalf : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { mTexture = NULL; - for (int i = 0; i < CUBE_FACE_COUNT; ++i) + for (size_t i = 0; i < CUBE_FACE_COUNT; ++i) { mRenderTarget[i] = NULL; } @@ -455,7 +452,7 @@ TextureStorage9_Cube::~TextureStorage9_Cube() { SafeRelease(mTexture); - for (int i = 0; i < CUBE_FACE_COUNT; ++i) + for (size_t i = 0; i < CUBE_FACE_COUNT; ++i) { SafeDelete(mRenderTarget[i]); } @@ -499,7 +496,7 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren { ASSERT(outRT); ASSERT(index.mipIndex == 0); - ASSERT(index.layerIndex >= 0 && index.layerIndex < CUBE_FACE_COUNT); + ASSERT(index.layerIndex >= 0 && static_cast<size_t>(index.layerIndex) < CUBE_FACE_COUNT); if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget()) { @@ -586,7 +583,7 @@ gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) TextureStorage9_Cube *dest9 = GetAs<TextureStorage9_Cube>(destStorage); int levels = getLevelCount(); - for (int f = 0; f < CUBE_FACE_COUNT; f++) + for (int f = 0; f < static_cast<int>(CUBE_FACE_COUNT); f++) { for (int i = 0; i < levels; i++) { diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h index 50e63a6f14f..f0455a9b710 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h @@ -89,7 +89,7 @@ class TextureStorage9_2D : public TextureStorage9 class TextureStorage9_EGLImage final : public TextureStorage9 { public: - TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image); + TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image, RenderTarget9 *renderTarget9); ~TextureStorage9_EGLImage() override; gl::Error getSurfaceLevel(GLenum target, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp index 86d1bd21dd3..08f4958e68c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp @@ -9,11 +9,14 @@ #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/copyimage.h" +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" #include "libANGLE/renderer/d3d/d3d9/vertexconversion.h" -#include "libANGLE/renderer/d3d/generatemip.h" -#include "libANGLE/renderer/d3d/loadimage.h" + +using namespace angle; namespace rx { @@ -24,43 +27,6 @@ namespace d3d9 const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); -struct D3D9FastCopyFormat -{ - GLenum destFormat; - GLenum destType; - ColorCopyFunction copyFunction; - - D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) - : destFormat(destFormat), destType(destType), copyFunction(copyFunction) - { } - - bool operator<(const D3D9FastCopyFormat& other) const - { - return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; - } -}; - -static const FastCopyFunctionMap &GetFastCopyFunctionMap(D3DFORMAT d3dFormat) -{ - switch (d3dFormat) - { - case D3DFMT_A8R8G8B8: - { - static FastCopyFunctionMap fastCopyMap; - if (fastCopyMap.empty()) - { - fastCopyMap[gl::FormatType(GL_RGBA, GL_UNSIGNED_BYTE)] = CopyBGRA8ToRGBA8; - } - return fastCopyMap; - } - default: - { - static FastCopyFunctionMap emptyMap; - return emptyMap; - } - } -} - // A map to determine the pixel size and mip generation function of a given D3D format typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap; @@ -75,18 +41,23 @@ D3DFormat::D3DFormat() luminanceBits(0), depthBits(0), stencilBits(0), - internalFormat(GL_NONE), - mipGenerationFunction(NULL), - colorReadFunction(NULL), - fastCopyFunctions() + info(nullptr) { } -static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth, - GLuint blockHeight, GLuint redBits, GLuint greenBits, GLuint blueBits, - GLuint alphaBits, GLuint lumBits, GLuint depthBits, GLuint stencilBits, - GLenum internalFormat, MipGenerationFunction mipFunc, - ColorReadFunction colorReadFunc) +static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, + D3DFORMAT format, + GLuint bits, + GLuint blockWidth, + GLuint blockHeight, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint lumBits, + GLuint depthBits, + GLuint stencilBits, + Format::ID formatID) { D3DFormat info; info.pixelBytes = bits / 8; @@ -99,47 +70,48 @@ static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, info.luminanceBits = lumBits; info.depthBits = depthBits; info.stencilBits = stencilBits; - info.internalFormat = internalFormat; - info.mipGenerationFunction = mipFunc; - info.colorReadFunction = colorReadFunc; - info.fastCopyFunctions = GetFastCopyFunctionMap(format); + info.info = &Format::Get(formatID); map->insert(std::make_pair(format, info)); } static D3D9FormatInfoMap BuildD3D9FormatInfoMap() { + using namespace angle; // For image reading and mipmap generation functions + D3D9FormatInfoMap map; - // | D3DFORMAT | S |W |H | R | G | B | A | L | D | S | Internal format | Mip generation function | Color read function | - InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, 0, 0, 0, 0, 8, 0, 0, GL_LUMINANCE8_EXT, GenerateMip<L8>, ReadColor<L8, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, 0, 0, 0, 8, 0, 0, 0, GL_ALPHA8_EXT, GenerateMip<A8>, ReadColor<A8, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, 0, 0, 0, 8, 8, 0, 0, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8>, ReadColor<A8L8, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip<A4R4G4B4>, ReadColor<A4R4G4B4, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip<A1R5G5B5>, ReadColor<A1R5G5B5, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, 5, 6, 5, 0, 0, 0, 0, GL_RGB565, GenerateMip<R5G6B5>, ReadColor<R5G6B5, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, 8, 8, 8, 0, 0, 0, 0, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, ReadColor<B8G8R8X8, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, 8, 8, 8, 8, 0, 0, 0, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, ReadColor<B8G8R8A8, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, 16, 0, 0, 0, 0, 0, 0, GL_R16F_EXT, GenerateMip<R16F>, ReadColor<R16F, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, 16, 16, 0, 0, 0, 0, 0, GL_RG16F_EXT, GenerateMip<R16G16F>, ReadColor<R16G16F, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, 16, 16, 16, 16, 0, 0, 0, GL_RGBA16F_EXT, GenerateMip<R16G16B16A16F>, ReadColor<R16G16B16A16F, GLfloat>); - InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, 32, 0, 0, 0, 0, 0, 0, GL_R32F_EXT, GenerateMip<R32F>, ReadColor<R32F, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, 32, 32, 0, 0, 0, 0, 0, GL_RG32F_EXT, GenerateMip<R32G32F>, ReadColor<R32G32F, GLfloat> ); - InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, 32, 32, 32, 32, 0, 0, 0, GL_RGBA32F_EXT, GenerateMip<R32G32B32A32F>, ReadColor<R32G32B32A32F, GLfloat>); - - InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, 0, 0, 0, 0, 0, 16, 0, GL_DEPTH_COMPONENT16, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 0, GL_DEPTH_COMPONENT16, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, 0, 0, 0, 0, 0, 32, 0, GL_DEPTH_COMPONENT32_OES, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ); + // clang-format off + // | D3DFORMAT | S |W |H | R | G | B | A | L | D | S | ANGLE format | + InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE ); + InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE ); + + InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, 0, 0, 0, 0, 8, 0, 0, Format::ID::L8_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, 0, 0, 0, 8, 0, 0, 0, Format::ID::A8_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, 0, 0, 0, 8, 8, 0, 0, Format::ID::L8A8_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, Format::ID::B4G4R4A4_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, Format::ID::B5G5R5A1_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, 5, 6, 5, 0, 0, 0, 0, Format::ID::R5G6B5_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, 8, 8, 8, 0, 0, 0, 0, Format::ID::B8G8R8X8_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, 8, 8, 8, 8, 0, 0, 0, Format::ID::B8G8R8A8_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, 16, 0, 0, 0, 0, 0, 0, Format::ID::R16_FLOAT ); + InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, 16, 16, 0, 0, 0, 0, 0, Format::ID::R16G16_FLOAT ); + InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, 16, 16, 16, 16, 0, 0, 0, Format::ID::R16G16B16A16_FLOAT ); + InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, 32, 0, 0, 0, 0, 0, 0, Format::ID::R32_FLOAT ); + InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, 32, 32, 0, 0, 0, 0, 0, Format::ID::R32G32_FLOAT ); + InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, 32, 32, 32, 32, 0, 0, 0, Format::ID::R32G32B32A32_FLOAT ); + + InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, 0, 0, 0, 0, 0, 16, 0, Format::ID::D16_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, Format::ID::D24_UNORM_S8_UINT ); + InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 0, Format::ID::D16_UNORM ); + InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, 0, 0, 0, 0, 0, 32, 0, Format::ID::D32_UNORM ); + + InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, Format::ID::D24_UNORM_S8_UINT ); + + InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, 0, 0, 0, 0, 0, 0, 0, Format::ID::BC1_RGBA_UNORM_BLOCK); + InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, Format::ID::BC2_RGBA_UNORM_BLOCK); + InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, Format::ID::BC3_RGBA_UNORM_BLOCK); + // clang-format on return map; } @@ -166,6 +138,8 @@ typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerM static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() { + using namespace angle; // For image initialization functions + InternalFormatInitialzerMap map; map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>)); @@ -174,28 +148,6 @@ static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() return map; } -// Each GL internal format corresponds to one D3D format and data loading function. -// Due to not all formats being available all the time, some of the function/format types are wrapped -// in templates that perform format support queries on a Renderer9 object which is supplied -// when requesting the function or format. - -typedef bool(*FallbackPredicateFunction)(); - -template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback> -static void FallbackLoad(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - if (pred()) - { - prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } - else - { - fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } -} - static void UnreachableLoad(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) @@ -232,8 +184,11 @@ static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalForma static D3D9FormatMap BuildD3D9FormatMap() { + using namespace angle; // For image loading functions + D3D9FormatMap map; + // clang-format off // | Internal format | Texture format | Render format | Load function | InsertD3D9FormatInfo(&map, GL_NONE, D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ); @@ -267,11 +222,11 @@ static D3D9FormatMap BuildD3D9FormatMap() InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ); InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ); - InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadA8ToBGRA8_SSE2, LoadA8ToBGRA8>); + InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadA8ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGB8_OES, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ); InsertD3D9FormatInfo(&map, GL_RGB565, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ); - InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad<gl::supportsSSE2, LoadRGBA8ToBGRA8_SSE2, LoadRGBA8ToBGRA8>); + InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA8ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGBA4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGB5_A1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_R8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ); @@ -290,6 +245,7 @@ static D3D9FormatMap BuildD3D9FormatMap() // then changing the format and loading function appropriately. InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 1> ); InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative<GLubyte, 2> ); + // clang-format on return map; } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h index b619bde3f2b..2937e14e763 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h @@ -15,6 +15,7 @@ #include "common/platform.h" #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/Format.h" #include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" @@ -43,12 +44,7 @@ struct D3DFormat GLuint depthBits; GLuint stencilBits; - GLenum internalFormat; - - MipGenerationFunction mipGenerationFunction; - ColorReadFunction colorReadFunction; - - FastCopyFunctionMap fastCopyFunctions; + const angle::Format *info; }; const D3DFormat &GetD3DFormatInfo(D3DFORMAT format); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp index bc1abe70d39..1883636a31c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp @@ -306,7 +306,7 @@ GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) { - GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).internalFormat; + GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).info->glInternalFormat; GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format; return convertedFormat == format; } @@ -646,9 +646,13 @@ WorkaroundsD3D GenerateWorkarounds() workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = false; workarounds.useInstancedPointSpriteEmulation = false; + + // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. + workarounds.expandIntegerPowExpressions = true; + return workarounds; } -} +} // namespace d3d9 -} +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h index 5e2b6d25490..ff6d55fd59a 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h @@ -10,7 +10,7 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ #define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ -#include "libANGLE/angletypes.h" +#include "common/Color.h" #include "libANGLE/Caps.h" #include "libANGLE/Error.h" diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h index 9df04110a0f..4893beb9af2 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h @@ -24,14 +24,6 @@ struct FormatType; namespace rx { -typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth, - const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch, - uint8_t *destData, size_t destRowPitch, size_t destDepthPitch); - -typedef void (*LoadImageFunction)(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/generatemip.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/generatemip.h deleted file mode 100644 index 4429d035acc..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/generatemip.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// generatemip.h: Defines the GenerateMip function, templated on the format -// type of the image for which mip levels are being generated. - -#ifndef LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ -#define LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ - -#include "libANGLE/angletypes.h" -#include "libANGLE/renderer/imageformats.h" - -namespace rx -{ - -template <typename T> -inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth, - const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch, - uint8_t *destData, size_t destRowPitch, size_t destDepthPitch); - -} - -#include "generatemip.inl" - -#endif // LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.cpp deleted file mode 100644 index e36ac9eec43..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.cpp +++ /dev/null @@ -1,826 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimage.cpp: Defines image loading functions. - -#include "libANGLE/renderer/d3d/loadimage.h" - -#include "libANGLE/renderer/imageformats.h" - -namespace rx -{ - -void LoadA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = static_cast<uint32_t>(source[x]) << 24; - } - } - } -} - -void LoadA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - // Same as loading to RGBA - LoadA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); -} - -void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); - float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0.0f; - dest[4 * x + 1] = 0.0f; - dest[4 * x + 2] = 0.0f; - dest[4 * x + 3] = source[x]; - } - } - } -} - -void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0; - dest[4 * x + 1] = 0; - dest[4 * x + 2] = 0; - dest[4 * x + 3] = source[x]; - } - } - } -} - -void LoadL8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint8_t sourceVal = source[x]; - dest[4 * x + 0] = sourceVal; - dest[4 * x + 1] = sourceVal; - dest[4 * x + 2] = sourceVal; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadL8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - // Same as loading to RGBA - LoadL8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); -} - -void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); - float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x]; - dest[4 * x + 1] = source[x]; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = 1.0f; - } - } - } -} - -void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x]; - dest[4 * x + 1] = source[x]; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = gl::Float16One; - } - } - } -} - -void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2 * x + 0]; - dest[4 * x + 1] = source[2 * x + 0]; - dest[4 * x + 2] = source[2 * x + 0]; - dest[4 * x + 3] = source[2 * x + 1]; - } - } - } -} - -void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - // Same as loading to RGBA - LoadLA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); -} - -void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); - float *dest = OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2 * x + 0]; - dest[4 * x + 1] = source[2 * x + 0]; - dest[4 * x + 2] = source[2 * x + 0]; - dest[4 * x + 3] = source[2 * x + 1]; - } - } - } -} - -void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2 * x + 0]; - dest[4 * x + 1] = source[2 * x + 0]; - dest[4 * x + 2] = source[2 * x + 0]; - dest[4 * x + 3] = source[2 * x + 1]; - } - } - } -} - -void LoadRGB8ToBGR565(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = - OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = - OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint8_t r8 = source[x * 3 + 0]; - uint8_t g8 = source[x * 3 + 1]; - uint8_t b8 = source[x * 3 + 2]; - auto r5 = static_cast<uint16_t>(r8 >> 3); - auto g6 = static_cast<uint16_t>(g8 >> 2); - auto b5 = static_cast<uint16_t>(b8 >> 3); - dest[x] = (r5 << 11) | (g6 << 5) | b5; - } - } - } -} - -void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x * 3 + 2]; - dest[4 * x + 1] = source[x * 3 + 1]; - dest[4 * x + 2] = source[x * 3 + 0]; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0x00; - dest[4 * x + 1] = source[x * 2 + 1]; - dest[4 * x + 2] = source[x * 2 + 0]; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadR8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0x00; - dest[4 * x + 1] = 0x00; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgb = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); - dest[4 * x + 1] = static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); - dest[4 * x + 2] = static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgb = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); - dest[4 * x + 1] = static_cast<uint8_t>(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); - dest[4 * x + 2] = static_cast<uint8_t>(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t rgba = source[x]; - dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - } - } -} - -void LoadRGBA8ToBGRA4(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = - OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = - OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t rgba8 = source[x]; - auto r4 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 4); - auto g4 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 12); - auto b4 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 20); - auto a4 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 28); - dest[x] = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4; - } - } - } -} - -void LoadRGBA4ToARGB4(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = ANGLE_ROTR16(source[x], 4); - } - } - } -} - -void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); - dest[4 * x + 1] = static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); - dest[4 * x + 2] = static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); - dest[4 * x + 3] = static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); - } - } - } -} - -void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); - dest[4 * x + 1] = static_cast<uint8_t>(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); - dest[4 * x + 2] = static_cast<uint8_t>(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); - dest[4 * x + 3] = static_cast<uint8_t>(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); - } - } - } -} - -void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t bgra = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12)); - dest[4 * x + 1] = static_cast<uint8_t>(((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8)); - dest[4 * x + 2] = static_cast<uint8_t>(((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4)); - dest[4 * x + 3] = static_cast<uint8_t>(((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0)); - } - } - } -} - -void LoadRGBA8ToBGR5A1(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = - OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = - OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t rgba8 = source[x]; - auto r5 = static_cast<uint16_t>((rgba8 & 0x000000FF) >> 3); - auto g5 = static_cast<uint16_t>((rgba8 & 0x0000FF00) >> 11); - auto b5 = static_cast<uint16_t>((rgba8 & 0x00FF0000) >> 19); - auto a1 = static_cast<uint16_t>((rgba8 & 0xFF000000) >> 31); - dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5; - } - } - } -} - -void LoadRGB10A2ToBGR5A1(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const R10G10B10A2 *source = - OffsetDataPointer<R10G10B10A2>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = - OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - R10G10B10A2 rgb10a2 = source[x]; - - uint16_t r5 = static_cast<uint16_t>(rgb10a2.R >> 5u); - uint16_t g5 = static_cast<uint16_t>(rgb10a2.G >> 5u); - uint16_t b5 = static_cast<uint16_t>(rgb10a2.B >> 5u); - uint16_t a1 = static_cast<uint16_t>(rgb10a2.A >> 1u); - - dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5; - } - } - } -} - -void LoadRGB5A1ToA1RGB5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = ANGLE_ROTR16(source[x], 1); - } - } - } -} - -void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); - dest[4 * x + 1] = static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); - dest[4 * x + 2] = static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); - dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0); - } - } - } -} - -void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); - dest[4 * x + 1] = static_cast<uint8_t>(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); - dest[4 * x + 2] = static_cast<uint8_t>(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); - dest[4 * x + 3] = static_cast<uint8_t>((rgba & 0x0001) ? 0xFF : 0); - } - } - } -} - -void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t bgra = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>(((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13)); - dest[4 * x + 1] = static_cast<uint8_t>(((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8)); - dest[4 * x + 2] = static_cast<uint8_t>(((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3)); - dest[4 * x + 3] = static_cast<uint8_t>((bgra & 0x0001) ? 0xFF : 0); - } - } - } -} - -void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t rgba = source[x]; - dest[4 * x + 0] = static_cast<uint8_t>((rgba & 0x000003FF) >> 2); - dest[4 * x + 1] = static_cast<uint8_t>((rgba & 0x000FFC00) >> 12); - dest[4 * x + 2] = static_cast<uint8_t>((rgba & 0x3FF00000) >> 22); - dest[4 * x + 3] = static_cast<uint8_t>(((rgba & 0xC0000000) >> 30) * 0x55); - } - } - } -} - -void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]), - gl::float16ToFloat32(source[x * 3 + 1]), - gl::float16ToFloat32(source[x * 3 + 2])); - } - } - } -} - -void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], source[x * 3 + 2]); - } - } - } -} - -void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer<uint16_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) << 0) | - (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) | - (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22); - } - } - } -} - -void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) << 0) | - (gl::float32ToFloat11(source[x * 3 + 1]) << 11) | - (gl::float32ToFloat10(source[x * 3 + 2]) << 22); - } - } - } -} - -void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t d = source[x] >> 8; - uint8_t s = source[x] & 0xFF; - dest[x] = d | (s << 24); - } - } - } -} - -void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer<float>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]); - dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]); - dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]); - dest[x * 4 + 3] = gl::Float16One; - } - } - } -} - -void LoadR32ToR16(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = source[x] >> 16; - } - } - } -} - -void LoadR32ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - - for (size_t x = 0; x < width; x++) - { - dest[x] = source[x] >> 8; - } - } - } -} - -} diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.h deleted file mode 100644 index 86ca1baf897..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage.h +++ /dev/null @@ -1,241 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimage.h: Defines image loading functions - -#ifndef LIBANGLE_RENDERER_LOADIMAGE_H_ -#define LIBANGLE_RENDERER_LOADIMAGE_H_ - -#include "libANGLE/angletypes.h" - -#include <stdint.h> - -namespace rx -{ - -void LoadA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB8ToBGR565(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA4ToARGB4(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA8ToBGRA4(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA8ToBGR5A1(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadRGB10A2ToBGR5A1(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadRGB5A1ToA1RGB5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template <typename type, size_t componentCount> -inline void LoadToNative(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template <typename type, uint32_t fourthComponentBits> -inline void LoadToNative3To4(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template <size_t componentCount> -inline void Load32FTo16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template <size_t blockWidth, size_t blockHeight, size_t blockSize> -inline void LoadCompressedToNative(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR32ToR16(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template <typename type, uint32_t firstBits, uint32_t secondBits, uint32_t thirdBits, uint32_t fourthBits> -inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR32ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template <typename T> -inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch); - -template <typename T> -inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch); - -} - -#include "loadimage.inl" - -#endif // LIBANGLE_RENDERER_LOADIMAGE_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp b/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp deleted file mode 100644 index c87d35c82be..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimageSSE2.cpp: Defines image loading functions. It's -// in a separated file for GCC, which can enable SSE usage only per-file, -// not for code blocks that use SSE2 explicitly. - -#include "libANGLE/renderer/d3d/loadimage.h" - -#include "common/platform.h" - -#ifdef ANGLE_USE_SSE -#include <emmintrin.h> -#endif - -namespace rx -{ - -void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ -#if defined(ANGLE_USE_SSE) - __m128i zeroWide = _mm_setzero_si128(); - - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer<uint8_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - - size_t x = 0; - - // Make output writes aligned - for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 0xF) != 0 && x < width); x++) - { - dest[x] = static_cast<uint32_t>(source[x]) << 24; - } - - for (; x + 7 < width; x += 8) - { - __m128i sourceData = _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&source[x])); - // Interleave each byte to 16bit, make the lower byte to zero - sourceData = _mm_unpacklo_epi8(zeroWide, sourceData); - // Interleave each 16bit to 32bit, make the lower 16bit to zero - __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData); - __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData); - - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo); - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi); - } - - // Handle the remainder - for (; x < width; x++) - { - dest[x] = static_cast<uint32_t>(source[x]) << 24; - } - } - } -#else - // Ensure that this function is reported as not implemented for ARM builds because - // the instructions below are not present for that architecture. - UNIMPLEMENTED(); - return; -#endif -} - -void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ -#if defined(ANGLE_USE_SSE) - __m128i brMask = _mm_set1_epi32(0x00ff00ff); - - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer<uint32_t>(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch); - - size_t x = 0; - - // Make output writes aligned - for (; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++) - { - uint32_t rgba = source[x]; - dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - - for (; x + 3 < width; x += 4) - { - __m128i sourceData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&source[x])); - // Mask out g and a, which don't change - __m128i gaComponents = _mm_andnot_si128(brMask, sourceData); - // Mask out b and r - __m128i brComponents = _mm_and_si128(sourceData, brMask); - // Swap b and r - __m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); - __m128i result = _mm_or_si128(gaComponents, brSwapped); - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result); - } - - // Perform leftover writes - for (; x < width; x++) - { - uint32_t rgba = source[x]; - dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - } - } -#else - // Ensure that this function is reported as not implemented for ARM builds because - // the instructions below are not present for that architecture. - UNIMPLEMENTED(); - return; -#endif -} - -} - diff --git a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage_etc.h b/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage_etc.h deleted file mode 100644 index dc64e0461b9..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/d3d/loadimage_etc.h +++ /dev/null @@ -1,140 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimage_etc.h: Decodes ETC and EAC encoded textures. - -#ifndef LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ -#define LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ - -#include "libANGLE/angletypes.h" - -#include <stdint.h> - -namespace rx -{ - -void LoadETC1RGB8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC1RGB8ToBC1(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACR11ToR8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACR11SToR8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACRG11ToRG8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACRG11SToRG8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2RGB8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2SRGB8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2RGB8A1ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2SRGB8A1ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2RGBA8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2SRGBA8ToSRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); -} - -#endif // LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gen_angle_format_table.py b/chromium/third_party/angle/src/libANGLE/renderer/gen_angle_format_table.py new file mode 100644 index 00000000000..005e5cb87ed --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/gen_angle_format_table.py @@ -0,0 +1,254 @@ +#!/usr/bin/python +# Copyright 2016 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# gen_angle_format_table.py: +# Code generation for ANGLE format map. +# + +import angle_format +from datetime import date +import json +import math +import pprint +import re +import sys + +template_autogen_h = """// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE format enumeration. + +namespace angle +{{ + +enum class Format::ID +{{ +{angle_format_enum} +}}; + +}} // namespace angle +""" + +template_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE Format table: +// Queries for typed format information from the ANGLE format enum. + +#include "libANGLE/renderer/Format.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +namespace angle +{{ + +// static +const Format &Format::Get(ID id) +{{ + // clang-format off + switch (id) + {{ +{angle_format_info_cases} + default: + UNREACHABLE(); + break; + }} + // clang-format on + + static const Format noneInfo(ID::NONE, GL_NONE, GL_NONE, nullptr, nullptr, 0, 0, 0, 0, 0, 0); + return noneInfo; +}} + +}} // namespace angle +""" + +def get_channel_struct(angle_format): + if 'bits' not in angle_format or angle_format['bits'] is None: + return None + if 'BLOCK' in angle_format['id']: + return None + bits = angle_format['bits'] + if 'D' in bits or 'S' in bits: + return None + + if 'channelStruct' in angle_format: + return angle_format['channelStruct'] + + struct_name = '' + for channel in angle_format['channels']: + if channel == 'r': + struct_name += 'R{}'.format(bits['R']) + if channel == 'g': + struct_name += 'G{}'.format(bits['G']) + if channel == 'b': + struct_name += 'B{}'.format(bits['B']) + if channel == 'a': + struct_name += 'A{}'.format(bits['A']) + if channel == 'l': + struct_name += 'L{}'.format(bits['L']) + if angle_format['componentType'] == 'float': + struct_name += 'F' + if angle_format['componentType'] == 'int' or angle_format['componentType'] == 'snorm': + struct_name += 'S' + return struct_name + +def get_mip_generation_function(angle_format): + channel_struct = get_channel_struct(angle_format) + if channel_struct == None or "BLOCK" in angle_format["id"]: + return 'nullptr' + return 'GenerateMip<' + channel_struct + '>' + +def get_color_read_function(angle_format): + channel_struct = get_channel_struct(angle_format) + if channel_struct == None: + return 'nullptr' + component_type_map = { + 'uint': 'GLuint', + 'int': 'GLint', + 'unorm': 'GLfloat', + 'snorm': 'GLfloat', + 'float': 'GLfloat' + } + return 'ReadColor<' + channel_struct + ', '+ component_type_map[angle_format['componentType']] + '>' + +format_entry_template = """{space}{{ +{space} static const Format info(ID::{id}, +{space} {glInternalFormat}, +{space} {fboImplementationInternalFormat}, +{space} {mipGenerationFunction}, +{space} {colorReadFunction}, +{space} {R}, {G}, {B}, {A}, {D}, {S}); +{space} return info; +{space}}} +""" + +def get_component_type(format_id): + if "SNORM" in format_id: + return "snorm" + elif "UNORM" in format_id: + return "unorm" + elif "FLOAT" in format_id: + return "float" + elif "UINT" in format_id: + return "uint" + elif "SINT" in format_id: + return "int" + elif format_id == "NONE": + return "none" + elif "SRGB" in format_id: + return "unorm" + else: + raise ValueError("Unknown component type for " + format_id) + +def get_channel_tokens(format_id): + r = re.compile(r'([ABDGLRS][\d]+)') + return filter(r.match, r.split(format_id)) + +def get_channels(format_id): + channels = '' + tokens = get_channel_tokens(format_id) + if len(tokens) == 0: + return None + for token in tokens: + channels += token[0].lower() + + return channels + +def get_bits(format_id): + bits = {} + tokens = get_channel_tokens(format_id) + if len(tokens) == 0: + return None + for token in tokens: + bits[token[0]] = int(token[1:]) + return bits + +def json_to_table_data(format_id, json, angle_to_gl): + + table_data = "" + + parsed = { + "space": " ", + "id": format_id, + } + + for k, v in json.iteritems(): + parsed[k] = v + + if "glInternalFormat" not in parsed: + parsed["glInternalFormat"] = angle_to_gl[format_id] + + if "fboImplementationInternalFormat" not in parsed: + parsed["fboImplementationInternalFormat"] = parsed["glInternalFormat"] + + if "componentType" not in parsed: + parsed["componentType"] = get_component_type(format_id) + + if "channels" not in parsed: + parsed["channels"] = get_channels(format_id) + + if "bits" not in parsed: + parsed["bits"] = get_bits(format_id) + + # Derived values. + parsed["mipGenerationFunction"] = get_mip_generation_function(parsed) + parsed["colorReadFunction"] = get_color_read_function(parsed) + + for channel in "ABDGLRS": + if parsed["bits"] != None and channel in parsed["bits"]: + parsed[channel] = parsed["bits"][channel] + else: + parsed[channel] = "0" + + return format_entry_template.format(**parsed) + +def parse_json_into_angle_format_switch_string(all_angle, json_data, angle_to_gl): + table_data = '' + for format_id in sorted(all_angle): + format_info = json_data[format_id] if format_id in json_data else {} + table_data += ' case ID::' + format_id + ':\n' + table_data += json_to_table_data(format_id, format_info, angle_to_gl) + + return table_data + +def gen_enum_string(all_angle): + enum_data = ' NONE' + for format_id in sorted(all_angle): + if format_id == 'NONE': + continue + enum_data += ',\n ' + format_id + return enum_data + +gl_to_angle = angle_format.load_forward_table('angle_format_map.json') +angle_to_gl = angle_format.load_inverse_table('angle_format_map.json') +json_data = angle_format.load_json('angle_format_data.json') +all_angle = angle_to_gl.keys() + +angle_format_cases = parse_json_into_angle_format_switch_string( + all_angle, json_data, angle_to_gl) +output_cpp = template_autogen_cpp.format( + copyright_year=date.today().year, + angle_format_info_cases=angle_format_cases) +with open('Format_autogen.cpp', 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() + +enum_data = gen_enum_string(all_angle) +output_h = template_autogen_h.format( + copyright_year=date.today().year, + angle_format_enum=enum_data) +with open('Format_ID_autogen.inl', 'wt') as out_file: + out_file.write(output_h) + out_file.close() diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gen_load_functions_table.py b/chromium/third_party/angle/src/libANGLE/renderer/gen_load_functions_table.py new file mode 100644 index 00000000000..eb3e4c5bf08 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/gen_load_functions_table.py @@ -0,0 +1,191 @@ +#!/usr/bin/python +# Copyright 2015 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# gen_load_functions_table.py: +# Code generation for the load function tables used for texture formats +# + +import json, sys +from datetime import date + +sys.path.append('../..') +import angle_format + +template = """// GENERATED FILE - DO NOT EDIT. +// Generated by gen_load_functions_table.py using data from load_functions_data.json +// +// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// load_functions_table: +// Contains the GetLoadFunctionsMap for texture_format_util.h +// + +#include "libANGLE/renderer/load_functions_table.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +using namespace rx; + +namespace angle +{{ + +namespace +{{ + +// ES3 image loading functions vary based on: +// - the GL internal format (supplied to glTex*Image*D) +// - the GL data type given (supplied to glTex*Image*D) +// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D +// device's capabilities) +// This map type determines which loading function to use, based on these three parameters. +// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. +void UnimplementedLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{{ + UNIMPLEMENTED(); +}} + +void UnreachableLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{{ + UNREACHABLE(); +}} + +{load_functions_data}}} // namespace + +LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, Format::ID {angle_format}) +{{ + // clang-format off + switch ({internal_format}) + {{ +{switch_data} + default: + {{ + static LoadFunctionMap emptyLoadFunctionsMap; + return emptyLoadFunctionsMap; + }} + }} + // clang-format on + +}} // GetLoadFunctionsMap + +}} // namespace angle +""" + +internal_format_param = 'internalFormat' +angle_format_param = 'angleFormat' +angle_format_unknown = 'NONE' + +def load_functions_name(internal_format, angle_format): + return internal_format[3:] + "_to_" + angle_format + +def unknown_func_name(internal_format): + return load_functions_name(internal_format, "default") + +def get_load_func(func_name, type_functions): + snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n" + snippet += "{\n" + snippet += " switch (type)\n" + snippet += " {\n" + for gl_type, load_function in sorted(type_functions.iteritems()): + snippet += " case " + gl_type + ":\n" + requiresConversion = str('LoadToNative<' not in load_function).lower() + snippet += " return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n" + snippet += " default:\n" + snippet += " UNREACHABLE();\n" + snippet += " return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n" + snippet += " }\n" + snippet += "}\n" + snippet += "\n" + + return snippet + +def get_unknown_load_func(angle_to_type_map, internal_format): + assert angle_format_unknown in angle_to_type_map + return get_load_func(unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown]) + +def parse_json(json_data): + table_data = '' + load_functions_data = '' + for internal_format, angle_to_type_map in sorted(json_data.iteritems()): + + s = ' ' + + table_data += s + 'case ' + internal_format + ':\n' + + do_switch = len(angle_to_type_map) > 1 or angle_to_type_map.keys()[0] != angle_format_unknown + + if do_switch: + table_data += s + '{\n' + s += ' ' + table_data += s + 'switch (' + angle_format_param + ')\n' + table_data += s + '{\n' + s += ' ' + + for angle_format, type_functions in sorted(angle_to_type_map.iteritems()): + + if angle_format == angle_format_unknown: + continue + + func_name = load_functions_name(internal_format, angle_format) + + # Main case statements + table_data += s + 'case Format::ID::' + angle_format + ':\n' + table_data += s + ' return ' + func_name + ';\n' + + if angle_format_unknown in angle_to_type_map: + for gl_type, load_function in angle_to_type_map[angle_format_unknown].iteritems(): + if gl_type not in type_functions: + type_functions[gl_type] = load_function + + load_functions_data += get_load_func(func_name, type_functions) + + if do_switch: + table_data += s + 'default:\n' + + if angle_format_unknown in angle_to_type_map: + table_data += s + ' return ' + unknown_func_name(internal_format) + ';\n' + load_functions_data += get_unknown_load_func(angle_to_type_map, internal_format) + else: + table_data += s + ' break;\n' + + if do_switch: + s = s[4:] + table_data += s + '}\n' + s = s[4:] + table_data += s + '}\n' + + return table_data, load_functions_data + +json_data = angle_format.load_json('load_functions_data.json') + +switch_data, load_functions_data = parse_json(json_data) +output = template.format(internal_format = internal_format_param, + angle_format = angle_format_param, + switch_data = switch_data, + load_functions_data = load_functions_data, + copyright_year = date.today().year) + +with open('load_functions_table_autogen.cpp', 'wt') as out_file: + out_file.write(output) + out_file.close() diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.cpp index 0a624dcb17d..b181822ff8b 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.cpp @@ -30,7 +30,7 @@ gl::Error CheckCompileStatus(const rx::FunctionsGL *functions, GLuint shader) return gl::Error(GL_OUT_OF_MEMORY, "Failed to compile internal blit shader."); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error CheckLinkStatus(const rx::FunctionsGL *functions, GLuint program) @@ -43,7 +43,7 @@ gl::Error CheckLinkStatus(const rx::FunctionsGL *functions, GLuint program) return gl::Error(GL_OUT_OF_MEMORY, "Failed to link internal blit program."); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } // anonymous namespace @@ -58,6 +58,9 @@ BlitGL::BlitGL(const FunctionsGL *functions, mWorkarounds(workarounds), mStateManager(stateManager), mBlitProgram(0), + mSourceTextureLocation(-1), + mScaleLocation(-1), + mOffsetLocation(-1), mScratchFBO(0), mVAO(0) { @@ -130,11 +133,7 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { - gl::Error error = initializeResources(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initializeResources()); // Blit the framebuffer to the first scratch texture const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); @@ -146,7 +145,6 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture, const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(copyTexImageFormat.internalFormat); - mStateManager->activeTexture(0); mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]); mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, copyTexImageFormat.internalFormat, sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height, 0); @@ -171,7 +169,6 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture, mScratchTextures[1], 0); // Render to the destination texture, sampling from the scratch texture - mStateManager->useProgram(mBlitProgram); mStateManager->setViewport(gl::Rectangle(0, 0, sourceArea.width, sourceArea.height)); mStateManager->setScissorTestEnabled(false); mStateManager->setDepthRange(0.0f, 1.0f); @@ -186,16 +183,192 @@ gl::Error BlitGL::copySubImageToLUMAWorkaroundTexture(GLuint texture, mStateManager->setRasterizerDiscardEnabled(false); mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]); + setScratchTextureParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST); + setScratchTextureParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mStateManager->activeTexture(0); + mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]); + + mStateManager->useProgram(mBlitProgram); + mFunctions->uniform1i(mSourceTextureLocation, 0); + mFunctions->uniform2f(mScaleLocation, 1.0, 1.0); + mFunctions->uniform2f(mOffsetLocation, 0.0, 0.0); + mStateManager->bindVertexArray(mVAO, 0); - mFunctions->drawArrays(GL_TRIANGLES, 0, 6); + mFunctions->drawArrays(GL_TRIANGLES, 0, 3); - // Finally, copy the swizzled texture to the destination texture + // Copy the swizzled texture to the destination texture mStateManager->bindTexture(textureType, texture); mFunctions->copyTexSubImage2D(target, static_cast<GLint>(level), destOffset.x, destOffset.y, 0, 0, sourceArea.width, sourceArea.height); - return gl::Error(GL_NO_ERROR); + // Finally orphan the scratch textures so they can be GCed by the driver. + orphanScratchTextures(); + + return gl::NoError(); +} + +gl::Error BlitGL::blitColorBufferWithShader(const gl::Framebuffer *source, + const gl::Framebuffer *dest, + const gl::Rectangle &sourceAreaIn, + const gl::Rectangle &destAreaIn, + GLenum filter) +{ + ANGLE_TRY(initializeResources()); + + // Normalize the destination area to have positive width and height because we will use + // glViewport to set it, which doesn't allow negative width or height. + gl::Rectangle sourceArea = sourceAreaIn; + gl::Rectangle destArea = destAreaIn; + if (destArea.width < 0) + { + destArea.x += destArea.width; + destArea.width = -destArea.width; + sourceArea.x += sourceArea.width; + sourceArea.width = -sourceArea.width; + } + if (destArea.height < 0) + { + destArea.y += destArea.height; + destArea.height = -destArea.height; + sourceArea.y += sourceArea.height; + sourceArea.height = -sourceArea.height; + } + + const gl::FramebufferAttachment *readAttachment = source->getReadColorbuffer(); + ASSERT(readAttachment->getSamples() <= 1); + + // Compute the part of the source that will be sampled. + gl::Rectangle inBoundsSource; + { + gl::Extents sourceSize = readAttachment->getSize(); + gl::Rectangle sourceBounds(0, 0, sourceSize.width, sourceSize.height); + gl::ClipRectangle(sourceArea, sourceBounds, &inBoundsSource); + + // Note that inBoundsSource will have lost the orientation information. + ASSERT(inBoundsSource.width >= 0 && inBoundsSource.height >= 0); + + // Early out when the sampled part is empty as the blit will be a noop, + // and it prevents a division by zero in later computations. + if (inBoundsSource.width == 0 || inBoundsSource.height == 0) + { + return gl::NoError(); + } + } + + // The blit will be emulated by getting the source of the blit in a texture and sampling it + // with CLAMP_TO_EDGE. The quad used to draw can trivially compute texture coordinates going + // from (0, 0) to (1, 1). These texture coordinates will need to be transformed to make two + // regions match: + // - The region of the texture representing the source framebuffer region that will be sampled + // - The region of the drawn quad that corresponds to non-clamped blit, this is the same as the + // region of the source rectangle that is inside the source attachment. + // + // These two regions, T (texture) and D (dest) are defined by their offset in texcoord space + // in (0, 1)^2 and their size in texcoord space in (-1, 1)^2. The size can be negative to + // represent the orientation of the blit. + // + // Then if P is the quad texcoord, Q the texcoord inside T, and R the texture texcoord: + // - Q = (P - D.offset) / D.size + // - Q = (R - T.offset) / T.size + // Hence R = (P - D.offset) / D.size * T.size - T.offset + // = P * (T.size / D.size) + (T.offset - D.offset * T.size / D.size) + + GLuint textureId; + gl::Vector2 TOffset; + gl::Vector2 TSize; + + // TODO(cwallez) once texture dirty bits are landed, reuse attached texture instead of using + // CopyTexImage2D + { + textureId = mScratchTextures[0]; + TOffset = gl::Vector2(0.0, 0.0); + TSize = gl::Vector2(1.0, 1.0); + if (sourceArea.width < 0) + { + TOffset.x = 1.0; + TSize.x = -1.0; + } + if (sourceArea.height < 0) + { + TOffset.y = 1.0; + TSize.y = -1.0; + } + + GLenum format = readAttachment->getFormat().info->internalFormat; + const FramebufferGL *sourceGL = GetImplAs<FramebufferGL>(source); + mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceGL->getFramebufferID()); + mStateManager->bindTexture(GL_TEXTURE_2D, textureId); + + mFunctions->copyTexImage2D(GL_TEXTURE_2D, 0, format, inBoundsSource.x, inBoundsSource.y, + inBoundsSource.width, inBoundsSource.height, 0); + } + + // Compute normalized sampled draw quad region + // It is the same as the region of the source rectangle that is in bounds. + gl::Vector2 DOffset; + gl::Vector2 DSize; + { + ASSERT(sourceArea.width != 0 && sourceArea.height != 0); + gl::Rectangle orientedInBounds = inBoundsSource; + if (sourceArea.width < 0) + { + orientedInBounds.x += orientedInBounds.width; + orientedInBounds.width = -orientedInBounds.width; + } + if (sourceArea.height < 0) + { + orientedInBounds.y += orientedInBounds.height; + orientedInBounds.height = -orientedInBounds.height; + } + + DOffset = + gl::Vector2(static_cast<float>(orientedInBounds.x - sourceArea.x) / sourceArea.width, + static_cast<float>(orientedInBounds.y - sourceArea.y) / sourceArea.height); + DSize = gl::Vector2(static_cast<float>(orientedInBounds.width) / sourceArea.width, + static_cast<float>(orientedInBounds.height) / sourceArea.height); + } + + ASSERT(DSize.x != 0.0 && DSize.y != 0.0); + gl::Vector2 texCoordScale = gl::Vector2(TSize.x / DSize.x, TSize.y / DSize.y); + gl::Vector2 texCoordOffset = gl::Vector2(TOffset.x - DOffset.x * texCoordScale.x, + TOffset.y - DOffset.y * texCoordScale.y); + + // Reset all the state except scissor and viewport + mStateManager->setDepthRange(0.0f, 1.0f); + mStateManager->setBlendEnabled(false); + mStateManager->setColorMask(true, true, true, true); + mStateManager->setSampleAlphaToCoverageEnabled(false); + mStateManager->setSampleCoverageEnabled(false); + mStateManager->setDepthTestEnabled(false); + mStateManager->setStencilTestEnabled(false); + mStateManager->setCullFaceEnabled(false); + mStateManager->setPolygonOffsetFillEnabled(false); + mStateManager->setRasterizerDiscardEnabled(false); + + // Use the viewport to draw exactly to the destination rectangle + mStateManager->setViewport(destArea); + + // Set uniforms + setScratchTextureParameter(GL_TEXTURE_MIN_FILTER, filter); + setScratchTextureParameter(GL_TEXTURE_MAG_FILTER, filter); + setScratchTextureParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + setScratchTextureParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + mStateManager->activeTexture(0); + mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[0]); + + mStateManager->useProgram(mBlitProgram); + mFunctions->uniform1i(mSourceTextureLocation, 0); + mFunctions->uniform2f(mScaleLocation, texCoordScale.x, texCoordScale.y); + mFunctions->uniform2f(mOffsetLocation, texCoordOffset.x, texCoordOffset.y); + + const FramebufferGL *destGL = GetImplAs<FramebufferGL>(dest); + mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, destGL->getFramebufferID()); + + mStateManager->bindVertexArray(mVAO, 0); + mFunctions->drawArrays(GL_TRIANGLES, 0, 3); + + return gl::NoError(); } gl::Error BlitGL::initializeResources() @@ -205,41 +378,38 @@ gl::Error BlitGL::initializeResources() mBlitProgram = mFunctions->createProgram(); // Compile the fragment shader + // It uses a single, large triangle, to avoid arithmetic precision issues where fragments + // with the same Y coordinate don't get exactly the same interpolated texcoord Y. const char *vsSource = "#version 150\n" "out vec2 v_texcoord;\n" + "uniform vec2 u_scale;\n" + "uniform vec2 u_offset;\n" "\n" "void main()\n" "{\n" - " const vec2 quad_positions[6] = vec2[6]\n" + " const vec2 quad_positions[3] = vec2[3]\n" " (\n" - " vec2(0.0f, 0.0f),\n" - " vec2(0.0f, 1.0f),\n" - " vec2(1.0f, 0.0f),\n" - "\n" - " vec2(0.0f, 1.0f),\n" - " vec2(1.0f, 0.0f),\n" - " vec2(1.0f, 1.0f)\n" + " vec2(-0.5f, 0.0f),\n" + " vec2( 1.5f, 0.0f),\n" + " vec2( 0.5f, 2.0f)\n" " );\n" "\n" " gl_Position = vec4((quad_positions[gl_VertexID] * 2.0) - 1.0, 0.0, 1.0);\n" - " v_texcoord = quad_positions[gl_VertexID];\n" + " v_texcoord = quad_positions[gl_VertexID] * u_scale + u_offset;\n" "}\n"; GLuint vs = mFunctions->createShader(GL_VERTEX_SHADER); mFunctions->shaderSource(vs, 1, &vsSource, nullptr); mFunctions->compileShader(vs); - gl::Error error = CheckCompileStatus(mFunctions, vs); + ANGLE_TRY(CheckCompileStatus(mFunctions, vs)); mFunctions->attachShader(mBlitProgram, vs); mFunctions->deleteShader(vs); - if (error.isError()) - { - return error; - } - // Compile the vertex shader + // It discards if the texcoord is outside (0, 1)^2 so the blitframebuffer workaround + // doesn't write when the point sampled is outside of the source framebuffer. const char *fsSource = "#version 150\n" "uniform sampler2D u_source_texture;\n" @@ -248,32 +418,28 @@ gl::Error BlitGL::initializeResources() "\n" "void main()\n" "{\n" + " if (clamp(v_texcoord, vec2(0.0), vec2(1.0)) != v_texcoord)\n" + " {\n" + " discard;\n" + " }\n" " output_color = texture(u_source_texture, v_texcoord);\n" "}\n"; GLuint fs = mFunctions->createShader(GL_FRAGMENT_SHADER); mFunctions->shaderSource(fs, 1, &fsSource, nullptr); mFunctions->compileShader(fs); - error = CheckCompileStatus(mFunctions, fs); + ANGLE_TRY(CheckCompileStatus(mFunctions, fs)); mFunctions->attachShader(mBlitProgram, fs); mFunctions->deleteShader(fs); - if (error.isError()) - { - return error; - } - mFunctions->linkProgram(mBlitProgram); - error = CheckLinkStatus(mFunctions, mBlitProgram); - if (error.isError()) - { - return error; - } + ANGLE_TRY(CheckLinkStatus(mFunctions, mBlitProgram)); - GLuint textureUniform = mFunctions->getUniformLocation(mBlitProgram, "u_source_texture"); + mSourceTextureLocation = mFunctions->getUniformLocation(mBlitProgram, "u_source_texture"); + mScaleLocation = mFunctions->getUniformLocation(mBlitProgram, "u_scale"); + mOffsetLocation = mFunctions->getUniformLocation(mBlitProgram, "u_offset"); mStateManager->useProgram(mBlitProgram); - mFunctions->uniform1i(textureUniform, 0); } for (size_t i = 0; i < ArraySize(mScratchTextures); i++) @@ -281,11 +447,6 @@ gl::Error BlitGL::initializeResources() if (mScratchTextures[i] == 0) { mFunctions->genTextures(1, &mScratchTextures[i]); - mStateManager->bindTexture(GL_TEXTURE_2D, mScratchTextures[i]); - - // Use nearest, non-mipmapped sampling with the scratch texture - mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - mFunctions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } } @@ -299,6 +460,27 @@ gl::Error BlitGL::initializeResources() mFunctions->genVertexArrays(1, &mVAO); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } + +void BlitGL::orphanScratchTextures() +{ + for (auto texture : mScratchTextures) + { + mStateManager->bindTexture(GL_TEXTURE_2D, texture); + mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + } +} + +void BlitGL::setScratchTextureParameter(GLenum param, GLenum value) +{ + for (auto texture : mScratchTextures) + { + mStateManager->bindTexture(GL_TEXTURE_2D, texture); + mFunctions->texParameteri(GL_TEXTURE_2D, param, value); + mFunctions->texParameteri(GL_TEXTURE_2D, param, value); + } } + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.h index 3ab8319bb13..b306ede2994 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/BlitGL.h @@ -52,14 +52,26 @@ class BlitGL : public angle::NonCopyable const gl::Rectangle &sourceArea, const gl::Framebuffer *source); + gl::Error blitColorBufferWithShader(const gl::Framebuffer *source, + const gl::Framebuffer *dest, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLenum filter); + gl::Error initializeResources(); private: + void orphanScratchTextures(); + void setScratchTextureParameter(GLenum param, GLenum value); + const FunctionsGL *mFunctions; const WorkaroundsGL &mWorkarounds; StateManagerGL *mStateManager; GLuint mBlitProgram; + GLint mSourceTextureLocation; + GLint mScaleLocation; + GLint mOffsetLocation; GLuint mScratchTextures[2]; GLuint mScratchFBO; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp index cd82733d774..b2e2f155ce9 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp @@ -53,7 +53,7 @@ BufferGL::~BufferGL() mBufferID = 0; } -gl::Error BufferGL::setData(const void* data, size_t size, GLenum usage) +gl::Error BufferGL::setData(GLenum /*target*/, const void *data, size_t size, GLenum usage) { mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); mFunctions->bufferData(DestBufferOperationTarget, size, data, usage); @@ -76,7 +76,7 @@ gl::Error BufferGL::setData(const void* data, size_t size, GLenum usage) return gl::Error(GL_NO_ERROR); } -gl::Error BufferGL::setSubData(const void* data, size_t size, size_t offset) +gl::Error BufferGL::setSubData(GLenum /*target*/, const void *data, size_t size, size_t offset) { mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); mFunctions->bufferSubData(DestBufferOperationTarget, offset, size, data); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.h index e787ec86e99..5985f8c2de4 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/BufferGL.h @@ -24,8 +24,8 @@ class BufferGL : public BufferImpl BufferGL(const FunctionsGL *functions, StateManagerGL *stateManager); ~BufferGL() override; - gl::Error setData(const void* data, size_t size, GLenum usage) override; - gl::Error setSubData(const void* data, size_t size, size_t offset) override; + gl::Error setData(GLenum target, const void *data, size_t size, GLenum usage) override; + gl::Error setSubData(GLenum target, const void *data, size_t size, size_t offset) override; gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) override; gl::Error map(GLenum access, GLvoid **mapPtr) override; gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.cpp index b9435589420..8d9e6d62634 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.cpp @@ -56,12 +56,14 @@ ShaderImpl *ContextGL::createShader(const gl::ShaderState &data) ProgramImpl *ContextGL::createProgram(const gl::ProgramState &data) { - return new ProgramGL(data, getFunctions(), getWorkaroundsGL(), getStateManager()); + return new ProgramGL(data, getFunctions(), getWorkaroundsGL(), getStateManager(), + getExtensions().pathRendering); } FramebufferImpl *ContextGL::createFramebuffer(const gl::FramebufferState &data) { - return new FramebufferGL(data, getFunctions(), getStateManager(), getWorkaroundsGL(), false); + return new FramebufferGL(data, getFunctions(), getStateManager(), getWorkaroundsGL(), + mRenderer->getBlitter(), false); } TextureImpl *ContextGL::createTexture(const gl::TextureState &state) @@ -101,10 +103,9 @@ FenceSyncImpl *ContextGL::createFenceSync() return new FenceSyncGL(getFunctions()); } -TransformFeedbackImpl *ContextGL::createTransformFeedback() +TransformFeedbackImpl *ContextGL::createTransformFeedback(const gl::TransformFeedbackState &state) { - return new TransformFeedbackGL(getFunctions(), getStateManager(), - getNativeCaps().maxTransformFeedbackSeparateComponents); + return new TransformFeedbackGL(state, getFunctions(), getStateManager()); } SamplerImpl *ContextGL::createSampler() @@ -222,24 +223,67 @@ void ContextGL::stencilThenCoverStrokePath(const gl::Path *path, mRenderer->stencilThenCoverStrokePath(mState, path, reference, mask, coverMode); } -void ContextGL::notifyDeviceLost() +void ContextGL::coverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) { - mRenderer->notifyDeviceLost(); + mRenderer->coverFillPathInstanced(mState, paths, coverMode, transformType, transformValues); } -bool ContextGL::isDeviceLost() const +void ContextGL::coverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) { - return mRenderer->isDeviceLost(); + mRenderer->coverStrokePathInstanced(mState, paths, coverMode, transformType, transformValues); } -bool ContextGL::testDeviceLost() +void ContextGL::stencilFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + mRenderer->stencilFillPathInstanced(mState, paths, fillMode, mask, transformType, + transformValues); +} + +void ContextGL::stencilStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + mRenderer->stencilStrokePathInstanced(mState, paths, reference, mask, transformType, + transformValues); +} + +void ContextGL::stencilThenCoverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + mRenderer->stencilThenCoverFillPathInstanced(mState, paths, coverMode, fillMode, mask, + transformType, transformValues); +} + +void ContextGL::stencilThenCoverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) { - return mRenderer->testDeviceLost(); + mRenderer->stencilThenCoverStrokePathInstanced(mState, paths, coverMode, reference, mask, + transformType, transformValues); } -bool ContextGL::testDeviceResettable() +GLenum ContextGL::getResetStatus() { - return mRenderer->testDeviceResettable(); + return mRenderer->getResetStatus(); } std::string ContextGL::getVendorString() const diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.h index 7a4375626ee..798a9043667 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/ContextGL.h @@ -58,7 +58,8 @@ class ContextGL : public ContextImpl FenceSyncImpl *createFenceSync() override; // Transform Feedback creation - TransformFeedbackImpl *createTransformFeedback() override; + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; // Sampler object creation SamplerImpl *createSampler() override; @@ -109,12 +110,39 @@ class ContextGL : public ContextImpl GLint reference, GLuint mask, GLenum coverMode) override; - - // TODO(jmadill): Investigate proper impl methods for this. - void notifyDeviceLost() override; - bool isDeviceLost() const override; - bool testDeviceLost() override; - bool testDeviceResettable() override; + void coverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) override; + void coverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) override; + void stencilFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) override; + void stencilStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) override; + void stencilThenCoverFillPathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) override; + void stencilThenCoverStrokePathInstanced(const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) override; + + // Device loss + GLenum getResetStatus() override; // Vendor and description strings. std::string getVendorString() const override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.cpp index fa443ca3b72..e5751332636 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.cpp @@ -9,10 +9,12 @@ #include "libANGLE/renderer/gl/DisplayGL.h" #include "libANGLE/AttributeMap.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" #include "libANGLE/Surface.h" #include "libANGLE/renderer/gl/ContextGL.h" #include "libANGLE/renderer/gl/RendererGL.h" +#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/SurfaceGL.h" #include <EGL/eglext.h> @@ -76,14 +78,17 @@ egl::Error DisplayGL::makeCurrent(egl::Surface *drawSurface, egl::Surface *readS return egl::Error(EGL_SUCCESS); } + // Pause transform feedback before making a new surface current, to workaround anglebug.com/1426 + ContextGL *glContext = GetImplAs<ContextGL>(context); + glContext->getStateManager()->pauseTransformFeedback(context->getContextState()); + SurfaceGL *glDrawSurface = GetImplAs<SurfaceGL>(drawSurface); return glDrawSurface->makeCurrent(); } -const gl::Version &DisplayGL::getMaxSupportedESVersion() const +gl::Version DisplayGL::getMaxSupportedESVersion() const { ASSERT(mRenderer != nullptr); return mRenderer->getMaxSupportedESVersion(); } - } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.h index 9a300c1007b..9f65158868b 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/DisplayGL.h @@ -39,10 +39,10 @@ class DisplayGL : public DisplayImpl egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override; virtual egl::Error getDriverVersion(std::string *version) const = 0; + gl::Version getMaxSupportedESVersion() const override; protected: RendererGL *getRenderer() const { return mRenderer; }; - const gl::Version &getMaxSupportedESVersion() const; private: virtual const FunctionsGL *getFunctionsGL() const = 0; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp index 6191a412d16..e253ada828e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp @@ -16,14 +16,18 @@ #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/gl/BlitGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/RenderbufferGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/TextureGL.h" #include "libANGLE/renderer/gl/WorkaroundsGL.h" +#include "libANGLE/renderer/gl/formatutilsgl.h" +#include "libANGLE/renderer/gl/renderergl_utils.h" #include "platform/Platform.h" using namespace gl; +using angle::CheckedNumeric; namespace rx { @@ -32,11 +36,13 @@ FramebufferGL::FramebufferGL(const FramebufferState &state, const FunctionsGL *functions, StateManagerGL *stateManager, const WorkaroundsGL &workarounds, + BlitGL *blitter, bool isDefault) : FramebufferImpl(state), mFunctions(functions), mStateManager(stateManager), mWorkarounds(workarounds), + mBlitter(blitter), mFramebufferID(0), mIsDefault(isDefault) { @@ -50,11 +56,13 @@ FramebufferGL::FramebufferGL(GLuint id, const FramebufferState &state, const FunctionsGL *functions, const WorkaroundsGL &workarounds, + BlitGL *blitter, StateManagerGL *stateManager) : FramebufferImpl(state), mFunctions(functions), mStateManager(stateManager), mWorkarounds(workarounds), + mBlitter(blitter), mFramebufferID(id), mIsDefault(true) { @@ -210,18 +218,16 @@ Error FramebufferGL::clearBufferfi(ContextImpl *context, GLenum FramebufferGL::getImplementationColorReadFormat() const { - const FramebufferAttachment *readAttachment = mState.getReadAttachment(); - GLenum internalFormat = readAttachment->getInternalFormat(); - const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat); - return internalFormatInfo.format; + const auto *readAttachment = mState.getReadAttachment(); + const Format &format = readAttachment->getFormat(); + return format.info->getReadPixelsFormat(); } GLenum FramebufferGL::getImplementationColorReadType() const { - const FramebufferAttachment *readAttachment = mState.getReadAttachment(); - GLenum internalFormat = readAttachment->getInternalFormat(); - const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat); - return internalFormatInfo.type; + const auto *readAttachment = mState.getReadAttachment(); + const Format &format = readAttachment->getFormat(); + return format.info->getReadPixelsType(); } Error FramebufferGL::readPixels(ContextImpl *context, @@ -235,10 +241,37 @@ Error FramebufferGL::readPixels(ContextImpl *context, const PixelPackState &packState = context->getGLState().getPackState(); mStateManager->setPixelPackState(packState); + nativegl::ReadPixelsFormat readPixelsFormat = + nativegl::GetReadPixelsFormat(mFunctions, mWorkarounds, format, type); + GLenum readFormat = readPixelsFormat.format; + GLenum readType = readPixelsFormat.type; + mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID); - mFunctions->readPixels(area.x, area.y, area.width, area.height, format, type, pixels); - return Error(GL_NO_ERROR); + if (mWorkarounds.packOverlappingRowsSeparatelyPackBuffer && packState.pixelBuffer.get() && + packState.rowLength != 0 && packState.rowLength < area.width) + { + return readPixelsRowByRowWorkaround(area, readFormat, readType, packState, pixels); + } + + if (mWorkarounds.packLastRowSeparatelyForPaddingInclusion) + { + gl::Extents size(area.width, area.height, 1); + + bool apply; + ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, packState, readFormat, readType, + false, pixels), + apply); + + if (apply) + { + return readPixelsPaddingWorkaround(area, readFormat, readType, packState, pixels); + } + } + + mFunctions->readPixels(area.x, area.y, area.width, area.height, readFormat, readType, pixels); + + return gl::NoError(); } Error FramebufferGL::blit(ContextImpl *context, @@ -248,15 +281,81 @@ Error FramebufferGL::blit(ContextImpl *context, GLenum filter) { const Framebuffer *sourceFramebuffer = context->getGLState().getReadFramebuffer(); - const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(sourceFramebuffer); + const Framebuffer *destFramebuffer = context->getGLState().getDrawFramebuffer(); + + bool needManualColorBlit = false; + + // The manual SRGB blit is only needed to perform correct linear interpolation. We don't + // need to make sure there is SRGB conversion for NEAREST as the values will be copied. + if (filter != GL_NEAREST) + { + + // Prior to OpenGL 4.4 BlitFramebuffer (section 18.3.1 of GL 4.3 core profile) reads: + // When values are taken from the read buffer, no linearization is performed, even + // if the format of the buffer is SRGB. + // Starting from OpenGL 4.4 (section 18.3.1) it reads: + // When values are taken from the read buffer, if FRAMEBUFFER_SRGB is enabled and the + // value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment + // corresponding to the read buffer is SRGB, the red, green, and blue components are + // converted from the non-linear sRGB color space according [...]. + { + const FramebufferAttachment *readAttachment = sourceFramebuffer->getReadColorbuffer(); + bool sourceSRGB = + readAttachment != nullptr && readAttachment->getColorEncoding() == GL_SRGB; + needManualColorBlit = + needManualColorBlit || (sourceSRGB && !mFunctions->isAtLeastGL(gl::Version(4, 4))); + } + + // Prior to OpenGL 4.2 BlitFramebuffer (section 4.3.2 of GL 4.1 core profile) reads: + // Blit operations bypass the fragment pipeline. The only fragment operations which + // affect a blit are the pixel ownership test and scissor test. + // Starting from OpenGL 4.2 (section 4.3.2) it reads: + // When values are written to the draw buffers, blit operations bypass the fragment + // pipeline. The only fragment operations which affect a blit are the pixel ownership + // test, the scissor test and sRGB conversion. + if (!needManualColorBlit) + { + bool destSRGB = false; + for (size_t i = 0; i < destFramebuffer->getDrawbufferStateCount(); ++i) + { + const FramebufferAttachment *attachment = destFramebuffer->getDrawBuffer(i); + if (attachment && attachment->getColorEncoding() == GL_SRGB) + { + destSRGB = true; + break; + } + } + + needManualColorBlit = + needManualColorBlit || (destSRGB && !mFunctions->isAtLeastGL(gl::Version(4, 2))); + } + } + // Enable FRAMEBUFFER_SRGB if needed + syncDrawState(); + + GLenum blitMask = mask; + if (needManualColorBlit && (mask & GL_COLOR_BUFFER_BIT)) + { + ANGLE_TRY(mBlitter->blitColorBufferWithShader(sourceFramebuffer, destFramebuffer, + sourceArea, destArea, filter)); + blitMask &= ~GL_COLOR_BUFFER_BIT; + } + + if (blitMask == 0) + { + return gl::NoError(); + } + + const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(sourceFramebuffer); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); mStateManager->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferID); mFunctions->blitFramebuffer(sourceArea.x, sourceArea.y, sourceArea.x1(), sourceArea.y1(), - destArea.x, destArea.y, destArea.x1(), destArea.y1(), mask, filter); + destArea.x, destArea.y, destArea.x1(), destArea.y1(), blitMask, + filter); - return Error(GL_NO_ERROR); + return gl::NoError(); } bool FramebufferGL::checkStatus() const @@ -342,17 +441,17 @@ void FramebufferGL::syncClearState(GLbitfield mask) if (mWorkarounds.doesSRGBClearsOnLinearFramebufferAttachments && (mask & GL_COLOR_BUFFER_BIT) != 0 && !mIsDefault) { - bool hasSRBAttachment = false; + bool hasSRGBAttachment = false; for (const auto &attachment : mState.getColorAttachments()) { if (attachment.isAttached() && attachment.getColorEncoding() == GL_SRGB) { - hasSRBAttachment = true; + hasSRGBAttachment = true; break; } } - mStateManager->setFramebufferSRGBEnabled(hasSRBAttachment); + mStateManager->setFramebufferSRGBEnabled(hasSRGBAttachment); } else { @@ -393,4 +492,71 @@ void FramebufferGL::syncClearBufferState(GLenum buffer, GLint drawBuffer) } } } +gl::Error FramebufferGL::readPixelsRowByRowWorkaround(const gl::Rectangle &area, + GLenum format, + GLenum type, + const gl::PixelPackState &pack, + GLvoid *pixels) const +{ + intptr_t offset = reinterpret_cast<intptr_t>(pixels); + + const gl::InternalFormat &glFormat = + gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type)); + GLuint rowBytes = 0; + ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, pack.alignment, pack.rowLength), + rowBytes); + GLuint skipBytes = 0; + ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes); + + gl::PixelPackState directPack; + directPack.pixelBuffer = pack.pixelBuffer; + directPack.alignment = 1; + mStateManager->setPixelPackState(directPack); + directPack.pixelBuffer.set(nullptr); + + offset += skipBytes; + for (GLint row = 0; row < area.height; ++row) + { + mFunctions->readPixels(area.x, row + area.y, area.width, 1, format, type, + reinterpret_cast<GLvoid *>(offset)); + offset += row * rowBytes; + } + + return gl::NoError(); +} + +gl::Error FramebufferGL::readPixelsPaddingWorkaround(const gl::Rectangle &area, + GLenum format, + GLenum type, + const gl::PixelPackState &pack, + GLvoid *pixels) const +{ + const gl::InternalFormat &glFormat = + gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type)); + GLuint rowBytes = 0; + ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, pack.alignment, pack.rowLength), + rowBytes); + GLuint skipBytes = 0; + ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, 0, pack, false), skipBytes); + + // Get all by the last row + if (area.height > 1) + { + mFunctions->readPixels(area.x, area.y, area.width, area.height - 1, format, type, pixels); + } + + // Get the last row manually + gl::PixelPackState directPack; + directPack.pixelBuffer = pack.pixelBuffer; + directPack.alignment = 1; + mStateManager->setPixelPackState(directPack); + directPack.pixelBuffer.set(nullptr); + + intptr_t lastRowOffset = + reinterpret_cast<intptr_t>(pixels) + skipBytes + (area.height - 1) * rowBytes; + mFunctions->readPixels(area.x, area.y + area.height - 1, area.width, 1, format, type, + reinterpret_cast<GLvoid *>(lastRowOffset)); + + return gl::NoError(); +} } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.h index 69d4aef351e..b02b7b9f46c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.h @@ -14,6 +14,7 @@ namespace rx { +class BlitGL; class FunctionsGL; class StateManagerGL; struct WorkaroundsGL; @@ -25,6 +26,7 @@ class FramebufferGL : public FramebufferImpl const FunctionsGL *functions, StateManagerGL *stateManager, const WorkaroundsGL &workarounds, + BlitGL *blitter, bool isDefault); // Constructor called when we need to create a FramebufferGL from an // existing framebuffer name, for example for the default framebuffer @@ -33,6 +35,7 @@ class FramebufferGL : public FramebufferImpl const gl::FramebufferState &data, const FunctionsGL *functions, const WorkaroundsGL &workarounds, + BlitGL *blitter, StateManagerGL *stateManager); ~FramebufferGL() override; @@ -85,9 +88,22 @@ class FramebufferGL : public FramebufferImpl void syncClearState(GLbitfield mask); void syncClearBufferState(GLenum buffer, GLint drawBuffer); + gl::Error readPixelsRowByRowWorkaround(const gl::Rectangle &area, + GLenum format, + GLenum type, + const gl::PixelPackState &pack, + GLvoid *pixels) const; + + gl::Error readPixelsPaddingWorkaround(const gl::Rectangle &area, + GLenum format, + GLenum type, + const gl::PixelPackState &pack, + GLvoid *pixels) const; + const FunctionsGL *mFunctions; StateManagerGL *mStateManager; const WorkaroundsGL &mWorkarounds; + BlitGL *mBlitter; GLuint mFramebufferID; bool mIsDefault; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp index f129717cce9..9c3964e4741 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.cpp @@ -433,6 +433,13 @@ FunctionsGL::FunctionsGL() coverStrokePathNV(nullptr), stencilThenCoverFillPathNV(nullptr), stencilThenCoverStrokePathNV(nullptr), + coverFillPathInstancedNV(nullptr), + coverStrokePathInstancedNV(nullptr), + stencilFillPathInstancedNV(nullptr), + stencilStrokePathInstancedNV(nullptr), + stencilThenCoverFillPathInstancedNV(nullptr), + stencilThenCoverStrokePathInstancedNV(nullptr), + programPathFragmentInputGenNV(nullptr), bindFragDataLocationIndexed(nullptr), bindSampler(nullptr), @@ -840,10 +847,13 @@ void FunctionsGL::initializeProcsDesktopGL() // Even though extensions are written against specific versions of GL, many drivers expose the extensions // in even older versions. Always try loading the extensions regardless of GL version. - // EXT_direct_state_access (loading only functions relevant to GL_NV_path_rendering here) - AssignGLExtensionEntryPoint(extensions, "GL_EXT_direct_state_access", loadProcAddress("glMatrixLoadfEXT"), &matrixLoadEXT); + // GL_ARB_program_interface_query (loading only functions relevant to GL_NV_path_rendering here) + AssignGLExtensionEntryPoint(extensions, "GL_ARB_program_interface_query", loadProcAddress("glGetProgramInterfaceiv"), &getProgramInterfaceiv); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_program_interface_query", loadProcAddress("glGetProgramResourceName"), &getProgramResourceName); + AssignGLExtensionEntryPoint(extensions, "GL_ARB_program_interface_query", loadProcAddress("glGetProgramResourceiv"), &getProgramResourceiv); // GL_NV_path_rendering + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glMatrixLoadfEXT"), &matrixLoadEXT); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGenPathsNV"), &genPathsNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glDeletePathsNV"), &delPathsNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathCommandsNV"), &pathCommandsNV); @@ -859,6 +869,13 @@ void FunctionsGL::initializeProcsDesktopGL() AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathNV"), &coverStrokePathNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathNV"), &stencilThenCoverFillPathNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathNV"), &stencilThenCoverStrokePathNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverFillPathInstancedNV"), &coverFillPathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathInstancedNV"), &coverStrokePathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilFillPathInstancedNV"), &stencilFillPathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilStrokePathInstancedNV"), &stencilStrokePathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathInstancedNV"), &stencilThenCoverFillPathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathInstancedNV"), &stencilThenCoverStrokePathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glProgramPathFragmentInputGenNV"), &programPathFragmentInputGenNV); // GL_NV_framebuffer_mixed_samples AssignGLExtensionEntryPoint(extensions, "GL_NV_framebuffer_mixed_samples", loadProcAddress("glCoverageModulationNV"), &coverageModulationNV); @@ -1006,6 +1023,12 @@ void FunctionsGL::initializeProcsDesktopGL() AssignGLExtensionEntryPoint(extensions, "GL_ARB_get_program_binary", loadProcAddress("glProgramBinary"), &programBinary); AssignGLExtensionEntryPoint(extensions, "GL_ARB_get_program_binary", loadProcAddress("glProgramParameteri"), &programParameteri); + // GL_ARB_robustness + AssignGLExtensionEntryPoint(extensions, "GL_ARB_robustness", loadProcAddress("glGetGraphicsResetStatusARB"), &getGraphicsResetStatus); + + // GL_KHR_robustness + AssignGLExtensionEntryPoint(extensions, "GL_KHR_robustness", loadProcAddress("glGetGraphicsResetStatus"), &getGraphicsResetStatus); + // 1.0 if (isAtLeastGL(gl::Version(1, 0))) { @@ -1758,10 +1781,9 @@ void FunctionsGL::initializeProcsGLES() profile = 0; // clang-format off - // EXT_direct_state_access (loading only functions relevant to GL_NV_path_rendering here) - AssignGLExtensionEntryPoint(extensions, "GL_EXT_direct_state_access", loadProcAddress("glMatrixLoadfEXT"), &matrixLoadEXT); // GL_NV_path_rendering + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glMatrixLoadfEXT"), &matrixLoadEXT); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glGenPathsNV"), &genPathsNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glDeletePathsNV"), &delPathsNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glPathCommandsNV"), &pathCommandsNV); @@ -1777,6 +1799,13 @@ void FunctionsGL::initializeProcsGLES() AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathNV"), &coverStrokePathNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathNV"), &stencilThenCoverFillPathNV); AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathNV"), &stencilThenCoverStrokePathNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverFillPathInstancedNV"), &coverFillPathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glCoverStrokePathInstancedNV"), &coverStrokePathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilFillPathInstancedNV"), &stencilFillPathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilStrokePathInstancedNV"), &stencilStrokePathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverFillPathInstancedNV"), &stencilThenCoverFillPathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glStencilThenCoverStrokePathInstancedNV"), &stencilThenCoverStrokePathInstancedNV); + AssignGLExtensionEntryPoint(extensions, "GL_NV_path_rendering", loadProcAddress("glProgramPathFragmentInputGenNV"), &programPathFragmentInputGenNV); // GL_OES_texture_3D AssignGLExtensionEntryPoint(extensions, "GL_OES_texture_3D", loadProcAddress("glTexImage3DOES"), &texImage3D); @@ -1862,6 +1891,12 @@ void FunctionsGL::initializeProcsGLES() AssignGLExtensionEntryPoint(extensions, "GL_OES_get_program_binary", loadProcAddress("glGetProgramBinaryOES"), &getProgramBinary); AssignGLExtensionEntryPoint(extensions, "GL_OES_get_program_binary", loadProcAddress("glProgramBinaryOES"), &programBinary); + // GL_EXT_robustness + AssignGLExtensionEntryPoint(extensions, "GL_EXT_robustness", loadProcAddress("glGetGraphicsResetStatusEXT"), &getGraphicsResetStatus); + + // GL_KHR_robustness + AssignGLExtensionEntryPoint(extensions, "GL_KHR_robustness", loadProcAddress("glGetGraphicsResetStatusKHR"), &getGraphicsResetStatus); + // 2.0 if (isAtLeastGLES(gl::Version(2, 0))) { diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.h index a5697cbf360..e790d96fe01 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/FunctionsGL.h @@ -392,10 +392,8 @@ class FunctionsGL PFNGLTEXIMAGE3DMULTISAMPLEPROC texImage3DMultisample; PFNGLWAITSYNCPROC waitSync; - // EXT_direct_state_access. Needed by NV_path_rendering. - PFNGLMATRIXLOADFEXTPROC matrixLoadEXT; - // NV_path_rendering (originally written against 3.2 compatibility profile) + PFNGLMATRIXLOADFEXTPROC matrixLoadEXT; PFNGLGENPATHSNVPROC genPathsNV; PFNGLDELETEPATHSNVPROC delPathsNV; PFNGLPATHCOMMANDSNVPROC pathCommandsNV; @@ -405,13 +403,19 @@ class FunctionsGL PFNGLGETPATHPARAMETERFVNVPROC getPathParameterfNV; PFNGLGETPATHPARAMETERIVNVPROC getPathParameteriNV; PFNGLPATHSTENCILFUNCNVPROC pathStencilFuncNV; - PFNGLSTENCILFILLPATHNVPROC stencilFillPathNV; PFNGLSTENCILSTROKEPATHNVPROC stencilStrokePathNV; PFNGLCOVERFILLPATHNVPROC coverFillPathNV; PFNGLCOVERSTROKEPATHNVPROC coverStrokePathNV; PFNGLSTENCILTHENCOVERFILLPATHNVPROC stencilThenCoverFillPathNV; PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC stencilThenCoverStrokePathNV; + PFNGLCOVERFILLPATHINSTANCEDNVPROC coverFillPathInstancedNV; + PFNGLCOVERSTROKEPATHINSTANCEDNVPROC coverStrokePathInstancedNV; + PFNGLSTENCILFILLPATHINSTANCEDNVPROC stencilFillPathInstancedNV; + PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC stencilStrokePathInstancedNV; + PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC stencilThenCoverFillPathInstancedNV; + PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC stencilThenCoverStrokePathInstancedNV; + PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC programPathFragmentInputGenNV; // 3.3 PFNGLBINDFRAGDATALOCATIONINDEXEDPROC bindFragDataLocationIndexed; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.cpp index 69479b691c9..e6ec58930c3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.cpp @@ -8,7 +8,9 @@ #include "libANGLE/renderer/gl/ProgramGL.h" +#include "common/angleutils.h" #include "common/debug.h" +#include "common/string_utils.h" #include "common/utilities.h" #include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/ShaderGL.h" @@ -23,11 +25,13 @@ namespace rx ProgramGL::ProgramGL(const gl::ProgramState &data, const FunctionsGL *functions, const WorkaroundsGL &workarounds, - StateManagerGL *stateManager) + StateManagerGL *stateManager, + bool enablePathRendering) : ProgramImpl(data), mFunctions(functions), mWorkarounds(workarounds), mStateManager(stateManager), + mEnablePathRendering(enablePathRendering), mProgramID(0) { ASSERT(mFunctions); @@ -97,53 +101,68 @@ LinkResult ProgramGL::link(const gl::ContextState &data, gl::InfoLog &infoLog) { preLink(); - // Set the transform feedback state - std::vector<const GLchar *> transformFeedbackVaryings; - for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames()) + if (mState.getAttachedComputeShader()) { - transformFeedbackVaryings.push_back(tfVarying.c_str()); - } + const ShaderGL *computeShaderGL = GetImplAs<ShaderGL>(mState.getAttachedComputeShader()); - if (transformFeedbackVaryings.empty()) - { - if (mFunctions->transformFeedbackVaryings) - { - mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr, - mState.getTransformFeedbackBufferMode()); - } + mFunctions->attachShader(mProgramID, computeShaderGL->getShaderID()); + + // Link and verify + mFunctions->linkProgram(mProgramID); + + // Detach the shaders + mFunctions->detachShader(mProgramID, computeShaderGL->getShaderID()); } else { - ASSERT(mFunctions->transformFeedbackVaryings); - mFunctions->transformFeedbackVaryings( - mProgramID, static_cast<GLsizei>(transformFeedbackVaryings.size()), - &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode()); - } + // Set the transform feedback state + std::vector<const GLchar *> transformFeedbackVaryings; + for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames()) + { + transformFeedbackVaryings.push_back(tfVarying.c_str()); + } - const ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(mState.getAttachedVertexShader()); - const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mState.getAttachedFragmentShader()); + if (transformFeedbackVaryings.empty()) + { + if (mFunctions->transformFeedbackVaryings) + { + mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr, + mState.getTransformFeedbackBufferMode()); + } + } + else + { + ASSERT(mFunctions->transformFeedbackVaryings); + mFunctions->transformFeedbackVaryings( + mProgramID, static_cast<GLsizei>(transformFeedbackVaryings.size()), + &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode()); + } - // Attach the shaders - mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID()); - mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID()); + const ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(mState.getAttachedVertexShader()); + const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mState.getAttachedFragmentShader()); - // Bind attribute locations to match the GL layer. - for (const sh::Attribute &attribute : mState.getAttributes()) - { - if (!attribute.staticUse) + // Attach the shaders + mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID()); + mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID()); + + // Bind attribute locations to match the GL layer. + for (const sh::Attribute &attribute : mState.getAttributes()) { - continue; - } + if (!attribute.staticUse) + { + continue; + } - mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str()); - } + mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str()); + } - // Link and verify - mFunctions->linkProgram(mProgramID); + // Link and verify + mFunctions->linkProgram(mProgramID); - // Detach the shaders - mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID()); - mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID()); + // Detach the shaders + mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID()); + mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID()); + } // Verify the link if (!checkLinkStatus(infoLog)) @@ -382,6 +401,26 @@ bool ProgramGL::getUniformBlockMemberInfo(const std::string &memberUniformName, return true; } +void ProgramGL::setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + ASSERT(mEnablePathRendering); + + for (const auto &input : mPathRenderingFragmentInputs) + { + if (input.name == inputName) + { + mFunctions->programPathFragmentInputGenNV(mProgramID, input.location, genMode, + components, coeffs); + ASSERT(mFunctions->getError() == GL_NO_ERROR); + return; + } + } + +} + void ProgramGL::preLink() { // Reset the program state @@ -389,6 +428,7 @@ void ProgramGL::preLink() mUniformBlockRealLocationMap.clear(); mSamplerBindings.clear(); mUniformIndexToSamplerIndex.clear(); + mPathRenderingFragmentInputs.clear(); } bool ProgramGL::checkLinkStatus(gl::InfoLog &infoLog) @@ -478,6 +518,71 @@ void ProgramGL::postLink() samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0); mSamplerBindings.push_back(samplerBinding); } + + // Discover CHROMIUM_path_rendering fragment inputs if enabled. + if (!mEnablePathRendering) + return; + + GLint numFragmentInputs = 0; + mFunctions->getProgramInterfaceiv(mProgramID, GL_FRAGMENT_INPUT_NV, GL_ACTIVE_RESOURCES, + &numFragmentInputs); + if (numFragmentInputs <= 0) + return; + + GLint maxNameLength = 0; + mFunctions->getProgramInterfaceiv(mProgramID, GL_FRAGMENT_INPUT_NV, GL_MAX_NAME_LENGTH, + &maxNameLength); + ASSERT(maxNameLength); + + for (GLint i = 0; i < numFragmentInputs; ++i) + { + std::string name; + name.resize(maxNameLength); + + GLsizei nameLen = 0; + mFunctions->getProgramResourceName(mProgramID, GL_FRAGMENT_INPUT_NV, i, maxNameLength, + &nameLen, &name[0]); + name.resize(nameLen); + + // Ignore built-ins + if (angle::BeginsWith(name, "gl_")) + continue; + + const GLenum kQueryProperties[] = {GL_LOCATION, GL_ARRAY_SIZE}; + GLint queryResults[ArraySize(kQueryProperties)]; + GLsizei queryLength = 0; + + mFunctions->getProgramResourceiv( + mProgramID, GL_FRAGMENT_INPUT_NV, i, static_cast<GLsizei>(ArraySize(kQueryProperties)), + kQueryProperties, static_cast<GLsizei>(ArraySize(queryResults)), &queryLength, + queryResults); + + ASSERT(queryLength == static_cast<GLsizei>(ArraySize(kQueryProperties))); + + PathRenderingFragmentInput baseElementInput; + baseElementInput.name = name; + baseElementInput.location = queryResults[0]; + mPathRenderingFragmentInputs.push_back(std::move(baseElementInput)); + + // If the input is an array it's denoted by [0] suffix on the variable + // name. We'll then create an entry per each array index where index > 0 + if (angle::EndsWith(name, "[0]")) + { + // drop the suffix + name.resize(name.size() - 3); + + const auto arraySize = queryResults[1]; + const auto baseLocation = queryResults[0]; + + for (GLint arrayIndex = 1; arrayIndex < arraySize; ++arrayIndex) + { + PathRenderingFragmentInput arrayElementInput; + arrayElementInput.name = name + "[" + ToString(arrayIndex) + "]"; + arrayElementInput.location = baseLocation + arrayIndex; + mPathRenderingFragmentInputs.push_back(std::move(arrayElementInput)); + } + } + } } } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.h index 901c6ca9367..88e2245fa26 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/ProgramGL.h @@ -9,6 +9,9 @@ #ifndef LIBANGLE_RENDERER_GL_PROGRAMGL_H_ #define LIBANGLE_RENDERER_GL_PROGRAMGL_H_ +#include <string> +#include <vector> + #include "libANGLE/renderer/gl/WorkaroundsGL.h" #include "libANGLE/renderer/ProgramImpl.h" @@ -30,7 +33,8 @@ class ProgramGL : public ProgramImpl ProgramGL(const gl::ProgramState &data, const FunctionsGL *functions, const WorkaroundsGL &workarounds, - StateManagerGL *stateManager); + StateManagerGL *stateManager, + bool enablePathRendering); ~ProgramGL() override; LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override; @@ -68,6 +72,11 @@ class ProgramGL : public ProgramImpl bool getUniformBlockMemberInfo(const std::string &memberUniformName, sh::BlockMemberInfo *memberInfoOut) const override; + void setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) override; + GLuint getProgramID() const; const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const; @@ -92,6 +101,15 @@ class ProgramGL : public ProgramImpl // A map from a mData.getUniforms() index to a mSamplerBindings index. std::vector<size_t> mUniformIndexToSamplerIndex; + struct PathRenderingFragmentInput + { + std::string name; + GLint location; + }; + std::vector<PathRenderingFragmentInput> mPathRenderingFragmentInputs; + + bool mEnablePathRendering; + GLuint mProgramID; }; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/RenderbufferGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/RenderbufferGL.h index eeb164378c2..0ff0faeae11 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/RenderbufferGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/RenderbufferGL.h @@ -38,12 +38,6 @@ class RenderbufferGL : public RenderbufferImpl GLuint getRenderbufferID() const; - gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, - FramebufferAttachmentRenderTarget **rtOut) override - { - return gl::Error(GL_OUT_OF_MEMORY, "Not supported on OpenGL"); - } - private: const FunctionsGL *mFunctions; const WorkaroundsGL &mWorkarounds; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.cpp index 682a8956722..da1a65687c1 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.cpp @@ -36,6 +36,24 @@ #include "libANGLE/renderer/gl/VertexArrayGL.h" #include "libANGLE/renderer/gl/renderergl_utils.h" +namespace +{ + +std::vector<GLuint> GatherPaths(const std::vector<gl::Path *> &paths) +{ + std::vector<GLuint> ret; + ret.reserve(paths.size()); + + for (const auto *p : paths) + { + const auto *pathObj = rx::GetImplAs<rx::PathGL>(p); + ret.push_back(pathObj->getPathID()); + } + return ret; +} + +} // namespace + #ifndef NDEBUG static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) @@ -104,6 +122,7 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at #ifndef NDEBUG if (mHasDebugOutput) { + mFunctions->enable(GL_DEBUG_OUTPUT); mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS); mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE); mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE); @@ -119,6 +138,17 @@ RendererGL::RendererGL(const FunctionsGL *functions, const egl::AttributeMap &at { mSkipDrawCalls = true; } + + if (mWorkarounds.initializeCurrentVertexAttributes) + { + GLint maxVertexAttribs = 0; + mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); + + for (GLint i = 0; i < maxVertexAttribs; ++i) + { + mFunctions->vertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 1.0f); + } + } } RendererGL::~RendererGL() @@ -315,48 +345,122 @@ void RendererGL::stencilThenCoverStrokePath(const gl::ContextState &state, ASSERT(mFunctions->getError() == GL_NO_ERROR); } -ContextImpl *RendererGL::createContext(const gl::ContextState &state) +void RendererGL::coverFillPathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) { - return new ContextGL(state, this); + const auto &pathObjs = GatherPaths(paths); + + mFunctions->coverFillPathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, + &pathObjs[0], 0, coverMode, transformType, + transformValues); + + ASSERT(mFunctions->getError() == GL_NO_ERROR); } +void RendererGL::coverStrokePathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjs = GatherPaths(paths); -void RendererGL::insertEventMarker(GLsizei length, const char *marker) + mFunctions->coverStrokePathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, + &pathObjs[0], 0, coverMode, transformType, + transformValues); + + ASSERT(mFunctions->getError() == GL_NO_ERROR); +} +void RendererGL::stencilFillPathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) { - mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, - GL_DEBUG_SEVERITY_NOTIFICATION, length, marker); + const auto &pathObjs = GatherPaths(paths); + + mFunctions->stencilFillPathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, + &pathObjs[0], 0, fillMode, mask, transformType, + transformValues); + + ASSERT(mFunctions->getError() == GL_NO_ERROR); } +void RendererGL::stencilStrokePathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjs = GatherPaths(paths); -void RendererGL::pushGroupMarker(GLsizei length, const char *marker) + mFunctions->stencilStrokePathInstancedNV(static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, + &pathObjs[0], 0, reference, mask, transformType, + transformValues); + + ASSERT(mFunctions->getError() == GL_NO_ERROR); +} + +void RendererGL::stencilThenCoverFillPathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) { - mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker); + const auto &pathObjs = GatherPaths(paths); + + mFunctions->stencilThenCoverFillPathInstancedNV( + static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, &pathObjs[0], 0, fillMode, mask, + coverMode, transformType, transformValues); + + ASSERT(mFunctions->getError() == GL_NO_ERROR); +} +void RendererGL::stencilThenCoverStrokePathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjs = GatherPaths(paths); + + mFunctions->stencilThenCoverStrokePathInstancedNV( + static_cast<GLsizei>(pathObjs.size()), GL_UNSIGNED_INT, &pathObjs[0], 0, reference, mask, + coverMode, transformType, transformValues); + + ASSERT(mFunctions->getError() == GL_NO_ERROR); } -void RendererGL::popGroupMarker() +GLenum RendererGL::getResetStatus() { - mFunctions->popDebugGroup(); + return mFunctions->getGraphicsResetStatus(); } -void RendererGL::notifyDeviceLost() +ContextImpl *RendererGL::createContext(const gl::ContextState &state) { - UNIMPLEMENTED(); + return new ContextGL(state, this); } -bool RendererGL::isDeviceLost() const +void RendererGL::insertEventMarker(GLsizei length, const char *marker) { - UNIMPLEMENTED(); - return bool(); + mFunctions->debugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 0, + GL_DEBUG_SEVERITY_NOTIFICATION, length, marker); } -bool RendererGL::testDeviceLost() +void RendererGL::pushGroupMarker(GLsizei length, const char *marker) { - UNIMPLEMENTED(); - return bool(); + mFunctions->pushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, length, marker); } -bool RendererGL::testDeviceResettable() +void RendererGL::popGroupMarker() { - UNIMPLEMENTED(); - return bool(); + mFunctions->popDebugGroup(); } std::string RendererGL::getVendorString() const diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.h index cb824845cc1..71f012055c1 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/RendererGL.h @@ -99,18 +99,51 @@ class RendererGL : angle::NonCopyable GLint reference, GLuint mask, GLenum coverMode); + void coverFillPathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void coverStrokePathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void stencilFillPathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + void stencilStrokePathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + + void stencilThenCoverFillPathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + void stencilThenCoverStrokePathInstanced(const gl::ContextState &state, + const std::vector<gl::Path *> &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + + GLenum getResetStatus(); // EXT_debug_marker void insertEventMarker(GLsizei length, const char *marker); void pushGroupMarker(GLsizei length, const char *marker); void popGroupMarker(); - // lost device - void notifyDeviceLost(); - bool isDeviceLost() const; - bool testDeviceLost(); - bool testDeviceResettable(); - std::string getVendorString() const; std::string getRendererDescription() const; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.cpp index 400917b3520..82de442a3a0 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.cpp @@ -36,8 +36,8 @@ ShaderGL::~ShaderGL() } } -int ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string * /*sourcePath*/) +ShCompileOptions ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string * /*sourcePath*/) { // Reset the previous state if (mShaderID != 0) @@ -48,13 +48,28 @@ int ShaderGL::prepareSourceAndReturnOptions(std::stringstream *sourceStream, *sourceStream << mData.getSource(); - int options = SH_INIT_GL_POSITION; + ShCompileOptions options = SH_INIT_GL_POSITION; if (mWorkarounds.doWhileGLSLCausesGPUHang) { options |= SH_REWRITE_DO_WHILE_LOOPS; } + if (mWorkarounds.emulateAbsIntFunction) + { + options |= SH_EMULATE_ABS_INT_FUNCTION; + } + + if (mWorkarounds.addAndTrueToLoopCondition) + { + options |= SH_ADD_AND_TRUE_TO_LOOP_CONDITION; + } + + if (mWorkarounds.emulateIsnanFloat) + { + options |= SH_EMULATE_ISNAN_FLOAT_FUNCTION; + } + return options; } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.h index f35d2f711e6..0ecd89ce63c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/ShaderGL.h @@ -25,8 +25,8 @@ class ShaderGL : public ShaderImpl ~ShaderGL() override; // ShaderImpl implementation - int prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string *sourcePath) override; + ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) override; bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override; std::string getDebugInfo() const override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp index 2be962d4b49..8ea230c4f2d 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp @@ -93,12 +93,14 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &ren mDepthMask(true), mStencilTestEnabled(false), mStencilFrontFunc(GL_ALWAYS), + mStencilFrontRef(0), mStencilFrontValueMask(static_cast<GLuint>(-1)), mStencilFrontStencilFailOp(GL_KEEP), mStencilFrontStencilPassDepthFailOp(GL_KEEP), mStencilFrontStencilPassDepthPassOp(GL_KEEP), mStencilFrontWritemask(static_cast<GLuint>(-1)), mStencilBackFunc(GL_ALWAYS), + mStencilBackRef(0), mStencilBackValueMask(static_cast<GLuint>(-1)), mStencilBackStencilFailOp(GL_KEEP), mStencilBackStencilPassDepthFailOp(GL_KEEP), @@ -117,6 +119,7 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, const gl::Caps &ren mClearDepth(1.0f), mClearStencil(0), mFramebufferSRGBEnabled(false), + mDitherEnabled(true), mTextureCubemapSeamlessEnabled(false), mMultisamplingEnabled(true), mSampleAlphaToOneEnabled(false), @@ -658,18 +661,26 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::ContextState &data, return setGenericDrawState(data); } -gl::Error StateManagerGL::onMakeCurrent(const gl::ContextState &data) +gl::Error StateManagerGL::pauseTransformFeedback(const gl::ContextState &data) { - const gl::State &state = data.getState(); - - // If the context has changed, pause the previous context's transform feedback and queries + // If the context is going to be changed, pause the previous context's transform feedback if (data.getContext() != mPrevDrawContext) { if (mPrevDrawTransformFeedback != nullptr) { mPrevDrawTransformFeedback->syncPausedState(true); } + } + return gl::Error(GL_NO_ERROR); +} +gl::Error StateManagerGL::onMakeCurrent(const gl::ContextState &data) +{ + const gl::State &state = data.getState(); + + // If the context has changed, pause the previous context's queries + if (data.getContext() != mPrevDrawContext) + { for (QueryGL *prevQuery : mCurrentQueries) { prevQuery->pause(); @@ -774,7 +785,7 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::ContextState &data) framebufferGL->syncDrawState(); // Seamless cubemaps are required for ES3 and higher contexts. - setTextureCubemapSeamlessEnabled(data.getClientVersion() >= 3); + setTextureCubemapSeamlessEnabled(data.getClientMajorVersion() >= 3); // Set the current transform feedback state gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); @@ -1503,7 +1514,7 @@ void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBit setPixelPackState(state.getPackState()); break; case gl::State::DIRTY_BIT_DITHER_ENABLED: - // TODO(jmadill): implement this + setDitherEnabled(state.isDitherEnabled()); break; case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT: // TODO(jmadill): implement this @@ -1578,6 +1589,22 @@ void StateManagerGL::setFramebufferSRGBEnabled(bool enabled) } } +void StateManagerGL::setDitherEnabled(bool enabled) +{ + if (mDitherEnabled != enabled) + { + mDitherEnabled = enabled; + if (mDitherEnabled) + { + mFunctions->enable(GL_DITHER); + } + else + { + mFunctions->disable(GL_DITHER); + } + } +} + void StateManagerGL::setMultisamplingStateEnabled(bool enabled) { if (mMultisamplingEnabled != enabled) diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.h index 10adb938fd6..35de237e9f1 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/StateManagerGL.h @@ -124,6 +124,8 @@ class StateManagerGL final : angle::NonCopyable void setFramebufferSRGBEnabled(bool enabled); + void setDitherEnabled(bool enabled); + void setMultisamplingStateEnabled(bool enabled); void setSampleAlphaToOneStateEnabled(bool enabled); @@ -146,6 +148,7 @@ class StateManagerGL final : angle::NonCopyable GLsizei instanceCount, const GLvoid **outIndices); + gl::Error pauseTransformFeedback(const gl::ContextState &data); gl::Error onMakeCurrent(const gl::ContextState &data); void syncState(const gl::State &state, const gl::State::DirtyBits &glDirtyBits); @@ -263,6 +266,7 @@ class StateManagerGL final : angle::NonCopyable GLint mClearStencil; bool mFramebufferSRGBEnabled; + bool mDitherEnabled; bool mTextureCubemapSeamlessEnabled; bool mMultisamplingEnabled; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp index fcdddebe04e..0fe7190a1ed 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.cpp @@ -26,6 +26,6 @@ SurfaceGL::~SurfaceGL() FramebufferImpl *SurfaceGL::createDefaultFramebuffer(const gl::FramebufferState &data) { return new FramebufferGL(data, mRenderer->getFunctions(), mRenderer->getStateManager(), - mRenderer->getWorkarounds(), true); + mRenderer->getWorkarounds(), mRenderer->getBlitter(), true); } } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.h index 329b562b9bf..117a9592d60 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/SurfaceGL.h @@ -22,12 +22,6 @@ class SurfaceGL : public SurfaceImpl SurfaceGL(const egl::SurfaceState &state, RendererGL *renderer); ~SurfaceGL() override; - gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, - FramebufferAttachmentRenderTarget **rtOut) override - { - return gl::Error(GL_OUT_OF_MEMORY, "Not supported on OpenGL"); - } - FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override; virtual egl::Error makeCurrent() = 0; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp index e9db0ad8aa5..623156fc058 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.cpp @@ -20,21 +20,27 @@ #include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/WorkaroundsGL.h" #include "libANGLE/renderer/gl/formatutilsgl.h" +#include "libANGLE/renderer/gl/renderergl_utils.h" + +using angle::CheckedNumeric; namespace rx { -static bool UseTexImage2D(GLenum textureType) +namespace +{ + +bool UseTexImage2D(GLenum textureType) { return textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP; } -static bool UseTexImage3D(GLenum textureType) +bool UseTexImage3D(GLenum textureType) { return textureType == GL_TEXTURE_2D_ARRAY || textureType == GL_TEXTURE_3D; } -static bool CompatibleTextureTarget(GLenum textureType, GLenum textureTarget) +bool CompatibleTextureTarget(GLenum textureType, GLenum textureTarget) { if (textureType != GL_TEXTURE_CUBE_MAP) { @@ -46,13 +52,13 @@ static bool CompatibleTextureTarget(GLenum textureType, GLenum textureTarget) } } -static bool IsLUMAFormat(GLenum format) +bool IsLUMAFormat(GLenum format) { return format == GL_LUMINANCE || format == GL_ALPHA || format == GL_LUMINANCE_ALPHA; } -static LUMAWorkaroundGL GetLUMAWorkaroundInfo(const gl::InternalFormat &originalFormatInfo, - GLenum destinationFormat) +LUMAWorkaroundGL GetLUMAWorkaroundInfo(const gl::InternalFormat &originalFormatInfo, + GLenum destinationFormat) { if (IsLUMAFormat(originalFormatInfo.format)) { @@ -67,23 +73,25 @@ static LUMAWorkaroundGL GetLUMAWorkaroundInfo(const gl::InternalFormat &original } } -static bool IsDepthStencilFormat(GLenum format) +bool IsDepthStencilFormat(GLenum format) { return format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL; } -static bool GetDepthStencilWorkaround(const gl::InternalFormat &originalFormatInfo) +bool GetDepthStencilWorkaround(const gl::InternalFormat &originalFormatInfo) { return IsDepthStencilFormat(originalFormatInfo.format); } -static LevelInfoGL GetLevelInfo(GLenum originalFormat, GLenum destinationFormat) +LevelInfoGL GetLevelInfo(GLenum originalFormat, GLenum destinationFormat) { const gl::InternalFormat &originalFormatInfo = gl::GetInternalFormatInfo(originalFormat); return LevelInfoGL(originalFormat, GetDepthStencilWorkaround(originalFormatInfo), GetLUMAWorkaroundInfo(originalFormatInfo, destinationFormat)); } +} // anonymous namespace + LUMAWorkaroundGL::LUMAWorkaroundGL() : LUMAWorkaroundGL(false, GL_NONE) { } @@ -134,8 +142,14 @@ TextureGL::~TextureGL() mTextureID = 0; } -gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureGL::setImage(GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() && unpack.rowLength != 0 && unpack.rowLength < size.width) @@ -143,13 +157,41 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat // The rows overlap in unpack memory. Upload the texture row by row to work around // driver bug. reserveTexImageToBeFilled(target, level, internalFormat, size, format, type); + + if (size.width == 0 || size.height == 0 || size.depth == 0) + { + return gl::NoError(); + } + gl::Box area(0, 0, 0, size.width, size.height, size.depth); - ANGLE_TRY(setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels)); + return setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels); } - else + + if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion) { - setImageHelper(target, level, internalFormat, size, format, type, pixels); + bool apply; + ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type, + UseTexImage3D(mState.mTarget), pixels), + apply); + + // The driver will think the pixel buffer doesn't have enough data, work around this bug + // by uploading the last row (and last level if 3D) separately. + if (apply) + { + reserveTexImageToBeFilled(target, level, internalFormat, size, format, type); + + if (size.width == 0 || size.height == 0 || size.depth == 0) + { + return gl::NoError(); + } + + gl::Box area(0, 0, 0, size.width, size.height, size.depth); + return setSubImagePaddingWorkaround(target, level, area, format, type, unpack, pixels); + } } + + setImageHelper(target, level, internalFormat, size, format, type, pixels); + return gl::NoError(); } @@ -212,32 +254,47 @@ gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &are nativegl::TexSubImageFormat texSubImageFormat = nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); + ASSERT(mLevelInfo[level].lumaWorkaround.enabled == + GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); + mStateManager->bindTexture(mState.mTarget, mTextureID); if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() && unpack.rowLength != 0 && unpack.rowLength < area.width) { - ANGLE_TRY(setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels)); + return setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels); } - else if (UseTexImage2D(mState.mTarget)) + + if (mWorkarounds.unpackLastRowSeparatelyForPaddingInclusion) + { + gl::Extents size(area.width, area.height, area.depth); + + bool apply; + ANGLE_TRY_RESULT(ShouldApplyLastRowPaddingWorkaround(size, unpack, format, type, + UseTexImage3D(mState.mTarget), pixels), + apply); + + // The driver will think the pixel buffer doesn't have enough data, work around this bug + // by uploading the last row (and last level if 3D) separately. + if (apply) + { + return setSubImagePaddingWorkaround(target, level, area, format, type, unpack, pixels); + } + } + + if (UseTexImage2D(mState.mTarget)) { ASSERT(area.z == 0 && area.depth == 1); mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width, area.height, texSubImageFormat.format, texSubImageFormat.type, pixels); } - else if (UseTexImage3D(mState.mTarget)) + else { + ASSERT(UseTexImage3D(mState.mTarget)); mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, area.width, area.height, area.depth, texSubImageFormat.format, texSubImageFormat.type, pixels); } - else - { - UNREACHABLE(); - } - - ASSERT(mLevelInfo[level].lumaWorkaround.enabled == - GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); return gl::Error(GL_NO_ERROR); } @@ -250,26 +307,23 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(GLenum target, const gl::PixelUnpackState &unpack, const uint8_t *pixels) { - gl::PixelUnpackState unpackToUse; - unpackToUse.pixelBuffer = unpack.pixelBuffer; - mStateManager->setPixelUnpackState(unpackToUse); - unpackToUse.pixelBuffer.set(nullptr); - GLenum sizedFormat = - gl::GetSizedInternalFormat(mState.getImageDesc(mState.mTarget, level).internalFormat, type); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat); + gl::PixelUnpackState directUnpack; + directUnpack.pixelBuffer = unpack.pixelBuffer; + directUnpack.alignment = 1; + mStateManager->setPixelUnpackState(directUnpack); + directUnpack.pixelBuffer.set(nullptr); + + const gl::InternalFormat &glFormat = + gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type)); GLuint rowBytes = 0; - ANGLE_TRY_RESULT( - formatInfo.computeRowPitch(GL_NONE, area.width, unpack.alignment, unpack.rowLength), - rowBytes); + ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength), + rowBytes); GLuint imageBytes = 0; - ANGLE_TRY_RESULT( - formatInfo.computeDepthPitch(GL_NONE, area.width, area.height, unpack.alignment, - unpack.rowLength, unpack.imageHeight), - imageBytes); + ANGLE_TRY_RESULT(glFormat.computeDepthPitch(area.height, unpack.imageHeight, rowBytes), + imageBytes); bool useTexImage3D = UseTexImage3D(mState.mTarget); GLuint skipBytes = 0; - ANGLE_TRY_RESULT(formatInfo.computeSkipBytes(rowBytes, imageBytes, unpack.skipImages, - unpack.skipRows, unpack.skipPixels, useTexImage3D), + ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D), skipBytes); const uint8_t *pixelsWithSkip = pixels + skipBytes; @@ -288,8 +342,9 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(GLenum target, } } } - else if (UseTexImage2D(mState.mTarget)) + else { + ASSERT(UseTexImage2D(mState.mTarget)); for (GLint row = 0; row < area.height; ++row) { GLint byteOffset = row * rowBytes; @@ -298,10 +353,89 @@ gl::Error TextureGL::setSubImageRowByRowWorkaround(GLenum target, area.width, 1, format, type, rowPixels); } } + return gl::NoError(); +} + +gl::Error TextureGL::setSubImagePaddingWorkaround(GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) +{ + const gl::InternalFormat &glFormat = + gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type)); + GLuint rowBytes = 0; + ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength), + rowBytes); + GLuint imageBytes = 0; + ANGLE_TRY_RESULT(glFormat.computeDepthPitch(area.height, unpack.imageHeight, rowBytes), + imageBytes); + bool useTexImage3D = UseTexImage3D(mState.mTarget); + GLuint skipBytes = 0; + ANGLE_TRY_RESULT(glFormat.computeSkipBytes(rowBytes, imageBytes, unpack, useTexImage3D), + skipBytes); + + gl::PixelUnpackState directUnpack; + directUnpack.pixelBuffer = unpack.pixelBuffer; + directUnpack.alignment = 1; + + if (useTexImage3D) + { + // Upload all but the last slice + if (area.depth > 1) + { + mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, + area.width, area.height, area.depth - 1, format, type, + pixels); + } + + // Upload the last slice but its last row + if (area.height > 1) + { + // Do not include skipBytes in the last image pixel start offset as it will be done by + // the driver + GLint lastImageOffset = (area.depth - 1) * imageBytes; + const GLubyte *lastImagePixels = pixels + lastImageOffset; + mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, + area.z + area.depth - 1, area.width, area.height - 1, 1, + format, type, lastImagePixels); + } + + // Upload the last row of the last slice "manually" + mStateManager->setPixelUnpackState(directUnpack); + + GLint lastRowOffset = + skipBytes + (area.depth - 1) * imageBytes + (area.height - 1) * rowBytes; + const GLubyte *lastRowPixels = pixels + lastRowOffset; + mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, + area.y + area.height - 1, area.z + area.depth - 1, area.width, 1, + 1, format, type, lastRowPixels); + } else { - UNREACHABLE(); + ASSERT(UseTexImage2D(mState.mTarget)); + + // Upload all but the last row + if (area.height > 1) + { + mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width, + area.height - 1, format, type, pixels); + } + + // Upload the last row "manually" + mStateManager->setPixelUnpackState(directUnpack); + + GLint lastRowOffset = skipBytes + (area.height - 1) * rowBytes; + const GLubyte *lastRowPixels = pixels + lastRowOffset; + mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, + area.y + area.height - 1, area.width, 1, format, type, + lastRowPixels); } + + directUnpack.pixelBuffer.set(nullptr); + return gl::NoError(); } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h index 540e6c3c692..72379bce08c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/TextureGL.h @@ -90,12 +90,6 @@ class TextureGL : public TextureImpl void syncState(size_t textureUnit) const; GLuint getTextureID() const; - gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, - FramebufferAttachmentRenderTarget **rtOut) override - { - return gl::Error(GL_OUT_OF_MEMORY, "Not supported on OpenGL"); - } - void setBaseLevel(GLuint) override {} private: @@ -120,6 +114,14 @@ class TextureGL : public TextureImpl const gl::PixelUnpackState &unpack, const uint8_t *pixels); + gl::Error setSubImagePaddingWorkaround(GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels); + const FunctionsGL *mFunctions; const WorkaroundsGL &mWorkarounds; StateManagerGL *mStateManager; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp index 6b7560ff06e..ae75a0f47dc 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp @@ -17,16 +17,15 @@ namespace rx { -TransformFeedbackGL::TransformFeedbackGL(const FunctionsGL *functions, - StateManagerGL *stateManager, - size_t maxTransformFeedbackBufferBindings) - : TransformFeedbackImpl(), +TransformFeedbackGL::TransformFeedbackGL(const gl::TransformFeedbackState &state, + const FunctionsGL *functions, + StateManagerGL *stateManager) + : TransformFeedbackImpl(state), mFunctions(functions), mStateManager(stateManager), mTransformFeedbackID(0), mIsActive(false), - mIsPaused(false), - mCurrentIndexedBuffers(maxTransformFeedbackBufferBindings) + mIsPaused(false) { mFunctions->genTransformFeedbacks(1, &mTransformFeedbackID); } @@ -35,11 +34,6 @@ TransformFeedbackGL::~TransformFeedbackGL() { mStateManager->deleteTransformFeedback(mTransformFeedbackID); mTransformFeedbackID = 0; - - for (auto &bufferBinding : mCurrentIndexedBuffers) - { - bufferBinding.set(nullptr); - } } void TransformFeedbackGL::begin(GLenum primitiveMode) @@ -70,30 +64,25 @@ void TransformFeedbackGL::bindIndexedBuffer(size_t index, const OffsetBindingPoi { // Directly bind buffer (not through the StateManager methods) because the buffer bindings are // tracked per transform feedback object - if (binding != mCurrentIndexedBuffers[index]) + mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID); + if (binding.get() != nullptr) { - mStateManager->bindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedbackID); - if (binding.get() != nullptr) + const BufferGL *bufferGL = GetImplAs<BufferGL>(binding.get()); + if (binding.getSize() != 0) { - const BufferGL *bufferGL = GetImplAs<BufferGL>(binding.get()); - if (binding.getSize() != 0) - { - mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, - static_cast<GLuint>(index), bufferGL->getBufferID(), - binding.getOffset(), binding.getSize()); - } - else - { - mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), - bufferGL->getBufferID()); - } + mFunctions->bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), + bufferGL->getBufferID(), binding.getOffset(), + binding.getSize()); } else { - mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), 0); + mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), + bufferGL->getBufferID()); } - - mCurrentIndexedBuffers[index] = binding; + } + else + { + mFunctions->bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), 0); } } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h index 7f72077e83b..f84edc0b741 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/TransformFeedbackGL.h @@ -20,9 +20,9 @@ class StateManagerGL; class TransformFeedbackGL : public TransformFeedbackImpl { public: - TransformFeedbackGL(const FunctionsGL *functions, - StateManagerGL *stateManager, - size_t maxTransformFeedbackBufferBindings); + TransformFeedbackGL(const gl::TransformFeedbackState &state, + const FunctionsGL *functions, + StateManagerGL *stateManager); ~TransformFeedbackGL() override; void begin(GLenum primitiveMode) override; @@ -46,8 +46,6 @@ class TransformFeedbackGL : public TransformFeedbackImpl mutable bool mIsActive; mutable bool mIsPaused; - - std::vector<OffsetBindingPointer<gl::Buffer>> mCurrentIndexedBuffers; }; } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h index 2549a2c4704..17d037d0c2c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/WorkaroundsGL.h @@ -21,7 +21,10 @@ struct WorkaroundsGL doWhileGLSLCausesGPUHang(false), finishDoesNotCauseQueriesToBeAvailable(false), alwaysCallUseProgramAfterLink(false), - unpackOverlappingRowsSeparatelyUnpackBuffer(false) + unpackOverlappingRowsSeparatelyUnpackBuffer(false), + emulateAbsIntFunction(false), + addAndTrueToLoopCondition(false), + emulateIsnanFloat(false) { } @@ -67,6 +70,41 @@ struct WorkaroundsGL // In the case of unpacking from a pixel unpack buffer, unpack overlapping rows row by row. bool unpackOverlappingRowsSeparatelyUnpackBuffer; + // In the case of packing to a pixel pack buffer, pack overlapping rows row by row. + bool packOverlappingRowsSeparatelyPackBuffer; + + // During initialization, assign the current vertex attributes to the spec-mandated defaults. + bool initializeCurrentVertexAttributes; + + // abs(i) where i is an integer returns unexpected result on Intel Mac. + // Emulate abs(i) with i * sign(i). + bool emulateAbsIntFunction; + + // On Intel Mac, calculation of loop conditions in for and while loop has bug. + // Add "&& true" to the end of the condition expression to work around the bug. + bool addAndTrueToLoopCondition; + + // When uploading textures from an unpack buffer, some drivers count an extra row padding when + // checking if the pixel unpack buffer is big enough. Tracking bug: http://anglebug.com/1512 + // For example considering the pixel buffer below where in memory, each row data (D) of the + // texture is followed by some unused data (the dots): + // +-------+--+ + // |DDDDDDD|..| + // |DDDDDDD|..| + // |DDDDDDD|..| + // |DDDDDDD|..| + // +-------A--B + // The last pixel read will be A, but the driver will think it is B, causing it to generate an + // error when the pixel buffer is just big enough. + bool unpackLastRowSeparatelyForPaddingInclusion; + + // Equivalent workaround when uploading data from a pixel pack buffer. + bool packLastRowSeparatelyForPaddingInclusion; + + // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around + // this bug, we use an expression to emulate function isnan(). + // Tracking bug: http://crbug.com/650547 + bool emulateIsnanFloat; }; } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h index 63e4d00fff1..0ba57b62bcd 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.h @@ -44,7 +44,6 @@ class DisplayCGL : public DisplayGL egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; egl::Error restoreLostDevice() override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm index f919919b817..b9d5f39b0c2 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm @@ -214,12 +214,6 @@ egl::ConfigSet DisplayCGL::generateConfigs() return configs; } -bool DisplayCGL::isDeviceLost() const -{ - // TODO(cwallez) investigate implementing this - return false; -} - bool DisplayCGL::testDeviceLost() { // TODO(cwallez) investigate implementing this diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h index 1e198bf5a3f..7cbb74da4c3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h @@ -53,7 +53,7 @@ class PbufferSurfaceCGL : public SurfaceGL const FunctionsGL *mFunctions; StateManagerGL *mStateManager; - const WorkaroundsGL &mWorkarounds; + RendererGL *mRenderer; GLuint mFramebuffer; GLuint mColorRenderbuffer; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm index b9689177eab..c03d3836f85 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.mm @@ -28,7 +28,7 @@ PbufferSurfaceCGL::PbufferSurfaceCGL(const egl::SurfaceState &state, mHeight(height), mFunctions(functions), mStateManager(renderer->getStateManager()), - mWorkarounds(renderer->getWorkarounds()), + mRenderer(renderer), mFramebuffer(0), mColorRenderbuffer(0), mDSRenderbuffer(0) @@ -136,7 +136,8 @@ EGLint PbufferSurfaceCGL::getSwapBehavior() const FramebufferImpl *PbufferSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state) { // TODO(cwallez) assert it happens only once? - return new FramebufferGL(mFramebuffer, state, mFunctions, mWorkarounds, mStateManager); + return new FramebufferGL(mFramebuffer, state, mFunctions, mRenderer->getWorkarounds(), + mRenderer->getBlitter(), mStateManager); } } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h index d8f1a14d759..165ab0486d1 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h @@ -88,6 +88,7 @@ class WindowSurfaceCGL : public SurfaceGL CGLContextObj mContext; const FunctionsGL *mFunctions; StateManagerGL *mStateManager; + RendererGL *mRenderer; const WorkaroundsGL &mWorkarounds; GLuint mFramebuffer; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm index b5375b1f9e9..c2ac4dca4be 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/cgl/WindowSurfaceCGL.mm @@ -154,11 +154,12 @@ mContext(context), mFunctions(functions), mStateManager(renderer->getStateManager()), + mRenderer(renderer), mWorkarounds(renderer->getWorkarounds()), mFramebuffer(0), mDSRenderbuffer(0) -{ - pthread_mutex_init(&mSwapState.mutex, nullptr); + { + pthread_mutex_init(&mSwapState.mutex, nullptr); } WindowSurfaceCGL::~WindowSurfaceCGL() @@ -324,7 +325,8 @@ EGLint WindowSurfaceCGL::getSwapBehavior() const FramebufferImpl *WindowSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state) { // TODO(cwallez) assert it happens only once? - return new FramebufferGL(mFramebuffer, state, mFunctions, mWorkarounds, mStateManager); + return new FramebufferGL(mFramebuffer, state, mFunctions, mWorkarounds, mRenderer->getBlitter(), + mStateManager); } } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp index 0ce5b5800d3..4956c5b3fe8 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp @@ -159,6 +159,7 @@ SurfaceImpl *DisplayAndroid::createWindowSurface(const egl::SurfaceState &state, EGL_NONE}; success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig); ASSERT(success && numConfig == 1); + UNUSED_ASSERTION_VARIABLE(success); return new WindowSurfaceEGL(state, mEGL, config, window, attribs.toIntVector(), mContext, getRenderer()); @@ -176,6 +177,7 @@ SurfaceImpl *DisplayAndroid::createPbufferSurface(const egl::SurfaceState &state EGL_NONE}; success = mEGL->chooseConfig(configAttribList, &config, 1, &numConfig); ASSERT(success && numConfig == 1); + UNUSED_ASSERTION_VARIABLE(success); return new PbufferSurfaceEGL(state, mEGL, config, attribs.toIntVector(), mContext, getRenderer()); @@ -212,8 +214,8 @@ void DisplayAndroid::getConfigAttrib(EGLConfig config, EGLint attribute, T *valu { EGLint tmp; EGLBoolean success = mEGL->getConfigAttrib(config, attribute, &tmp); - UNUSED_ASSERTION_VARIABLE(success); ASSERT(success == EGL_TRUE); + UNUSED_ASSERTION_VARIABLE(success); *value = tmp; } @@ -231,6 +233,7 @@ egl::ConfigSet DisplayAndroid::generateConfigs() success = mEGL->chooseConfig(mConfigAttribList.data(), configs.data(), numConfigs, &numConfigs2); ASSERT(success == EGL_TRUE && numConfigs2 == numConfigs); + UNUSED_ASSERTION_VARIABLE(success); for (int i = 0; i < numConfigs; i++) { @@ -331,11 +334,6 @@ egl::ConfigSet DisplayAndroid::generateConfigs() return configSet; } -bool DisplayAndroid::isDeviceLost() const -{ - return false; -} - bool DisplayAndroid::testDeviceLost() { return false; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h index f3b67619425..693532fb43f 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.h @@ -49,7 +49,6 @@ class DisplayAndroid : public DisplayEGL egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; egl::Error restoreLostDevice() override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp index ccaa2c045d3..982c80693a1 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.cpp @@ -308,9 +308,9 @@ uint32_t DisplayOzone::Buffer::getDRMFB() FramebufferGL *DisplayOzone::Buffer::framebufferGL(const gl::FramebufferState &state) { - return new FramebufferGL(mGLFB, state, mDisplay->mFunctionsGL, - mDisplay->getRenderer()->getWorkarounds(), - mDisplay->getRenderer()->getStateManager()); + return new FramebufferGL( + mGLFB, state, mDisplay->mFunctionsGL, mDisplay->getRenderer()->getWorkarounds(), + mDisplay->getRenderer()->getBlitter(), mDisplay->getRenderer()->getStateManager()); } void DisplayOzone::Buffer::present() @@ -900,11 +900,6 @@ egl::ConfigSet DisplayOzone::generateConfigs() return configs; } -bool DisplayOzone::isDeviceLost() const -{ - return false; -} - bool DisplayOzone::testDeviceLost() { return false; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h index b15ecf2636d..55a188c3e8e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/egl/ozone/DisplayOzone.h @@ -131,7 +131,6 @@ class DisplayOzone final : public DisplayEGL egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; egl::Error restoreLostDevice() override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp index 1688be11615..c5219b4b8bf 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.cpp @@ -438,6 +438,32 @@ static GLenum GetNativeType(const FunctionsGL *functions, return result; } +static GLenum GetNativeReadType(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum type) +{ + GLenum result = type; + + if (functions->standard == STANDARD_GL_DESKTOP) + { + if (type == GL_HALF_FLOAT_OES) + { + // The enums differ for the OES half float extensions and desktop GL spec. Update it. + result = GL_HALF_FLOAT; + } + } + + return result; +} + +static GLenum GetNativeReadFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format) +{ + GLenum result = format; + return result; +} + TexImageFormat GetTexImageFormat(const FunctionsGL *functions, const WorkaroundsGL &workarounds, GLenum internalFormat, @@ -512,6 +538,16 @@ RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions, GetNativeInternalFormat(functions, workarounds, internalFormat, internalFormat); return result; } +ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format, + GLenum type) +{ + ReadPixelsFormat result; + result.format = GetNativeReadFormat(functions, workarounds, format); + result.type = GetNativeReadType(functions, workarounds, type); + return result; +} } } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.h index 547d4783e7d..616f37af24c 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/formatutilsgl.h @@ -112,6 +112,16 @@ struct RenderbufferFormat RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions, const WorkaroundsGL &workarounds, GLenum internalFormat); + +struct ReadPixelsFormat +{ + GLenum format; + GLenum type; +}; +ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions, + const WorkaroundsGL &workarounds, + GLenum format, + GLenum type); } } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp index fe7ed7be6a7..0358a428ed5 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.cpp @@ -19,6 +19,7 @@ #include "libANGLE/Surface.h" #include "libANGLE/renderer/gl/glx/PbufferSurfaceGLX.h" #include "libANGLE/renderer/gl/glx/WindowSurfaceGLX.h" +#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/renderergl_utils.h" #include "third_party/libXNVCtrl/NVCtrl.h" #include "third_party/libXNVCtrl/NVCtrlLib.h" @@ -117,6 +118,7 @@ DisplayGLX::DisplayGLX() mHasMultisample(false), mHasARBCreateContext(false), mHasARBCreateContextProfile(false), + mHasARBCreateContextRobustness(false), mHasEXTCreateContextES2Profile(false), mSwapControl(SwapControl::Absent), mMinSwapInterval(0), @@ -159,6 +161,7 @@ egl::Error DisplayGLX::initialize(egl::Display *display) mHasMultisample = mGLX.minorVersion > 3 || mGLX.hasExtension("GLX_ARB_multisample"); mHasARBCreateContext = mGLX.hasExtension("GLX_ARB_create_context"); mHasARBCreateContextProfile = mGLX.hasExtension("GLX_ARB_create_context_profile"); + mHasARBCreateContextRobustness = mGLX.hasExtension("GLX_ARB_create_context_robustness"); mHasEXTCreateContextES2Profile = mGLX.hasExtension("GLX_EXT_create_context_es2_profile"); std::string clientVendor = mGLX.getClientString(GLX_VENDOR); @@ -386,7 +389,7 @@ SurfaceImpl *DisplayGLX::createWindowSurface(const egl::SurfaceState &state, ASSERT(configIdToGLXConfig.count(configuration->configID) > 0); glx::FBConfig fbConfig = configIdToGLXConfig[configuration->configID]; - return new WindowSurfaceGLX(state, mGLX, this, this->getRenderer(), window, mGLX.getDisplay(), + return new WindowSurfaceGLX(state, mGLX, this, getRenderer(), window, mGLX.getDisplay(), mContext, fbConfig); } @@ -401,7 +404,7 @@ SurfaceImpl *DisplayGLX::createPbufferSurface(const egl::SurfaceState &state, EGLint height = static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0)); bool largest = (attribs.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE); - return new PbufferSurfaceGLX(state, this->getRenderer(), width, height, largest, mGLX, mContext, + return new PbufferSurfaceGLX(state, getRenderer(), width, height, largest, mGLX, mContext, fbConfig); } @@ -725,21 +728,18 @@ egl::ConfigSet DisplayGLX::generateConfigs() return configs; } -bool DisplayGLX::isDeviceLost() const -{ - // UNIMPLEMENTED(); - return false; -} - bool DisplayGLX::testDeviceLost() { - // UNIMPLEMENTED(); + if (mHasARBCreateContextRobustness) + { + return getRenderer()->getResetStatus() != GL_NO_ERROR; + } + return false; } egl::Error DisplayGLX::restoreLostDevice() { - UNIMPLEMENTED(); return egl::Error(EGL_BAD_DISPLAY); } @@ -751,7 +751,7 @@ bool DisplayGLX::isValidNativeWindow(EGLNativeWindowType window) const // fail if the window doesn't exist (the rational is that these function // are used by window managers). Out of these function we use XQueryTree // as it seems to be the simplest; a drawback is that it will allocate - // memory for the list of children, becasue we use a child window for + // memory for the list of children, because we use a child window for // WindowSurface. Window root; Window parent; @@ -891,11 +891,11 @@ const FunctionsGL *DisplayGLX::getFunctionsGL() const void DisplayGLX::generateExtensions(egl::DisplayExtensions *outExtensions) const { + outExtensions->createContextRobustness = mHasARBCreateContextRobustness; } void DisplayGLX::generateCaps(egl::Caps *outCaps) const { - // UNIMPLEMENTED(); outCaps->textureNPOT = true; } @@ -913,6 +913,12 @@ egl::Error DisplayGLX::createContextAttribs(glx::FBConfig, { std::vector<int> attribs; + if (mHasARBCreateContextRobustness) + { + attribs.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); + attribs.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB); + } + if (version.valid()) { attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB); @@ -933,6 +939,9 @@ egl::Error DisplayGLX::createContextAttribs(glx::FBConfig, // When creating a context with glXCreateContextAttribsARB, a variety of X11 errors can // be generated. To prevent these errors from crashing our process, we simply ignore // them and only look if GLXContext was created. + // Process all events before setting the error handler to avoid desynchronizing XCB instances + // (the error handler is NOT per-display). + XSync(mXDisplay, False); auto oldErrorHandler = XSetErrorHandler(IgnoreX11Errors); *context = mGLX.createContextAttribsARB(mContextConfig, nullptr, True, attribs.data()); XSetErrorHandler(oldErrorHandler); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h index c83860fa883..79198395ded 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/DisplayGLX.h @@ -62,7 +62,6 @@ class DisplayGLX : public DisplayGL egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; egl::Error restoreLostDevice() override; @@ -126,6 +125,7 @@ class DisplayGLX : public DisplayGL bool mHasMultisample; bool mHasARBCreateContext; bool mHasARBCreateContextProfile; + bool mHasARBCreateContextRobustness; bool mHasEXTCreateContextES2Profile; enum class SwapControl diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/platform_glx.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/platform_glx.h index ee3a7ac551f..3ffb609d555 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/platform_glx.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/glx/platform_glx.h @@ -116,6 +116,12 @@ #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +// GLX_ARB_create_context_robustness +#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 + // GLX_EXT_create_context_es2_profile #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp index a63580540be..b9e6e53b1f4 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.cpp @@ -11,6 +11,8 @@ #include <limits> +#include "common/mathutil.h" +#include "libANGLE/Buffer.h" #include "libANGLE/Caps.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/gl/FunctionsGL.h" @@ -20,6 +22,8 @@ #include <algorithm> #include <sstream> +using angle::CheckedNumeric; + namespace rx { VendorID GetVendorID(const FunctionsGL *functions) @@ -120,6 +124,13 @@ static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name) return result; } +static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index) +{ + GLint result; + functions->getIntegeri_v(name, index, &result); + return result; +} + static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index) { GLint result[2] = {}; @@ -186,8 +197,8 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM } } - // Start by assuming ES3 support and work down - *maxSupportedESVersion = gl::Version(3, 0); + // Start by assuming ES3.1 support and work down + *maxSupportedESVersion = gl::Version(3, 1); // Table 6.28, implementation dependent values if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->hasGLExtension("GL_ARB_ES3_compatibility") || @@ -592,6 +603,164 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM LimitVersion(maxSupportedESVersion, gl::Version(2, 0)); } + if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_texture_multisample")) + { + caps->maxFramebufferWidth = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH); + caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT); + caps->maxFramebufferSamples = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_texture_multisample")) + { + caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS); + caps->maxColorTextureSamples = QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES); + caps->maxDepthTextureSamples = QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES); + caps->maxIntegerSamples = QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_vertex_attrib_binding")) + { + caps->maxVertexAttribRelativeOffset = + QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET); + caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS); + caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")) + { + caps->maxCombinedShaderOutputResources = + QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES); + caps->maxFragmentShaderStorageBlocks = + QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS); + caps->maxVertexShaderStorageBlocks = + QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS); + caps->maxShaderStorageBufferBindings = + QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS); + caps->maxShaderStorageBlockSize = + QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE); + caps->maxCombinedShaderStorageBlocks = + QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS); + caps->shaderStorageBufferOffsetAlignment = + QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_compute_shader")) + { + for (GLuint index = 0u; index < 3u; ++index) + { + caps->maxComputeWorkGroupCount[index] = + QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index); + + caps->maxComputeWorkGroupSize[index] = + QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index); + } + caps->maxComputeWorkGroupInvocations = + QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS); + caps->maxComputeUniformBlocks = QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS); + caps->maxComputeTextureImageUnits = + QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS); + caps->maxComputeSharedMemorySize = + QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE); + caps->maxComputeUniformComponents = + QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS); + caps->maxComputeAtomicCounterBuffers = + QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS); + caps->maxComputeAtomicCounters = + QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS); + caps->maxComputeImageUniforms = QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS); + caps->maxCombinedComputeUniformComponents = + QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS); + caps->maxComputeShaderStorageBlocks = + QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_explicit_uniform_location")) + { + caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_texture_gather")) + { + caps->minProgramTextureGatherOffset = + QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET); + caps->maxProgramTextureGatherOffset = + QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_shader_image_load_store")) + { + caps->maxVertexImageUniforms = QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS); + caps->maxFragmentImageUniforms = + QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS); + caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS); + caps->maxCombinedImageUniforms = + QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + + if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) || + functions->hasGLExtension("GL_ARB_shader_atomic_counters")) + { + caps->maxVertexAtomicCounterBuffers = + QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS); + caps->maxVertexAtomicCounters = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS); + caps->maxFragmentAtomicCounterBuffers = + QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS); + caps->maxFragmentAtomicCounters = + QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS); + caps->maxAtomicCounterBufferBindings = + QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS); + caps->maxAtomicCounterBufferSize = + QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE); + caps->maxCombinedAtomicCounterBuffers = + QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS); + caps->maxCombinedAtomicCounters = + QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS); + } + else + { + LimitVersion(maxSupportedESVersion, gl::Version(3, 0)); + } + // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time // if the max uniform vectors is too large. Artificially limit the maximum until the test is // updated. @@ -682,13 +851,26 @@ void GenerateCaps(const FunctionsGL *functions, gl::Caps *caps, gl::TextureCapsM functions->hasGLExtension("GL_NV_framebuffer_mixed_samples") || functions->hasGLESExtension("GL_NV_framebuffer_mixed_samples"); - // if NV_path_rendering is to be supported then EXT_direct_state_access - // must also be available. NV_path_rendering needs some of the matrix loads - // from this extension. - extensions->pathRendering = (functions->hasGLExtension("GL_NV_path_rendering") && - functions->hasGLExtension("GL_EXT_direct_state_access")) || - (functions->hasGLESExtension("GL_NV_path_rendering") && - functions->hasGLESExtension("GL_EXT_direct_state_access")); + extensions->robustness = functions->isAtLeastGL(gl::Version(4, 5)) || + functions->hasGLExtension("GL_KHR_robustness") || + functions->hasGLExtension("GL_ARB_robustness") || + functions->isAtLeastGLES(gl::Version(3, 2)) || + functions->hasGLESExtension("GL_KHR_robustness") || + functions->hasGLESExtension("GL_EXT_robustness"); + + // NV_path_rendering + // We also need interface query which is available in + // >= 4.3 core or ARB_interface_query or >= GLES 3.1 + const bool canEnableGLPathRendering = + functions->hasGLExtension("GL_NV_path_rendering") && + (functions->hasGLExtension("GL_ARB_program_interface_query") || + functions->isAtLeastGL(gl::Version(4, 3))); + + const bool canEnableESPathRendering = + functions->hasGLESExtension("GL_NV_path_rendering") && + functions->isAtLeastGLES(gl::Version(3, 1)); + + extensions->pathRendering = canEnableGLPathRendering || canEnableESPathRendering; } void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workarounds) @@ -703,6 +885,12 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround workarounds->rgba4IsNotSupportedForColorRendering = functions->standard == STANDARD_GL_DESKTOP && vendor == VENDOR_ID_INTEL; + workarounds->emulateAbsIntFunction = vendor == VENDOR_ID_INTEL; + + workarounds->addAndTrueToLoopCondition = vendor == VENDOR_ID_INTEL; + + workarounds->emulateIsnanFloat = vendor == VENDOR_ID_INTEL; + workarounds->doesSRGBClearsOnLinearFramebufferAttachments = functions->standard == STANDARD_GL_DESKTOP && (vendor == VENDOR_ID_INTEL || vendor == VENDOR_ID_AMD); @@ -718,6 +906,17 @@ void GenerateWorkarounds(const FunctionsGL *functions, WorkaroundsGL *workaround workarounds->alwaysCallUseProgramAfterLink = true; workarounds->unpackOverlappingRowsSeparatelyUnpackBuffer = vendor == VENDOR_ID_NVIDIA; + workarounds->packOverlappingRowsSeparatelyPackBuffer = vendor == VENDOR_ID_NVIDIA; + + workarounds->initializeCurrentVertexAttributes = vendor == VENDOR_ID_NVIDIA; + +#if defined(ANGLE_PLATFORM_APPLE) + workarounds->unpackLastRowSeparatelyForPaddingInclusion = true; + workarounds->packLastRowSeparatelyForPaddingInclusion = true; +#else + workarounds->unpackLastRowSeparatelyForPaddingInclusion = vendor == VENDOR_ID_NVIDIA; + workarounds->packLastRowSeparatelyForPaddingInclusion = vendor == VENDOR_ID_NVIDIA; +#endif } } @@ -773,4 +972,45 @@ uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions, return nullptr; } } + +gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size, + const gl::PixelStoreStateBase &state, + GLenum format, + GLenum type, + bool is3D, + const void *pixels) +{ + if (state.pixelBuffer.get() == nullptr) + { + return false; + } + + // We are using an pack or unpack buffer, compute what the driver thinks is going to be the + // last byte read or written. If it is past the end of the buffer, we will need to use the + // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation. + CheckedNumeric<size_t> checkedEndByte; + CheckedNumeric<size_t> pixelBytes; + size_t rowPitch; + + const gl::InternalFormat &glFormat = + gl::GetInternalFormatInfo(gl::GetSizedInternalFormat(format, type)); + ANGLE_TRY_RESULT(glFormat.computePackUnpackEndByte(type, size, state, is3D), checkedEndByte); + ANGLE_TRY_RESULT(glFormat.computeRowPitch(type, size.width, state.alignment, state.rowLength), + rowPitch); + pixelBytes = glFormat.computePixelBytes(type); + + checkedEndByte += reinterpret_cast<intptr_t>(pixels); + + // At this point checkedEndByte is the actual last byte read. + // The driver adds an extra row padding (if any), mimic it. + ANGLE_TRY_CHECKED_MATH(pixelBytes); + if (pixelBytes.ValueOrDie() * size.width < rowPitch) + { + checkedEndByte += rowPitch - pixelBytes * size.width; + } + + ANGLE_TRY_CHECKED_MATH(checkedEndByte); + + return checkedEndByte.ValueOrDie() > static_cast<size_t>(state.pixelBuffer->getSize()); +} } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.h index 3b0cab27e7b..bd5a425d09b 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/renderergl_utils.h @@ -11,6 +11,7 @@ #define LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_ #include "libANGLE/angletypes.h" +#include "libANGLE/Error.h" #include "libANGLE/renderer/gl/functionsgl_typedefs.h" #include <string> @@ -47,6 +48,13 @@ uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions, size_t offset, size_t length, GLbitfield access); + +gl::ErrorOrResult<bool> ShouldApplyLastRowPaddingWorkaround(const gl::Extents &size, + const gl::PixelStoreStateBase &state, + GLenum format, + GLenum type, + bool is3D, + const void *pixels); } #endif // LIBANGLE_RENDERER_GL_RENDERERGLUTILS_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp index e07457d1044..7c5214e8227 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.cpp @@ -36,6 +36,7 @@ DXGISwapChainWindowSurfaceWGL::DXGISwapChainWindowSurfaceWGL(const egl::SurfaceS mWindow(window), mStateManager(renderer->getStateManager()), mWorkarounds(renderer->getWorkarounds()), + mRenderer(renderer), mFunctionsGL(functionsGL), mFunctionsWGL(functionsWGL), mDevice(device), @@ -292,7 +293,8 @@ EGLint DXGISwapChainWindowSurfaceWGL::getSwapBehavior() const FramebufferImpl *DXGISwapChainWindowSurfaceWGL::createDefaultFramebuffer( const gl::FramebufferState &data) { - return new FramebufferGL(mFramebufferID, data, mFunctionsGL, mWorkarounds, mStateManager); + return new FramebufferGL(mFramebufferID, data, mFunctionsGL, mWorkarounds, + mRenderer->getBlitter(), mStateManager); } egl::Error DXGISwapChainWindowSurfaceWGL::setObjectsLocked(bool locked) diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h index 66444da9b6c..f516239c9e7 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h @@ -66,6 +66,7 @@ class DXGISwapChainWindowSurfaceWGL : public SurfaceGL StateManagerGL *mStateManager; const WorkaroundsGL &mWorkarounds; + RendererGL *mRenderer; const FunctionsGL *mFunctionsGL; const FunctionsWGL *mFunctionsWGL; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp index b3011a6e575..324140934cd 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.cpp @@ -12,6 +12,7 @@ #include "libANGLE/Config.h" #include "libANGLE/Display.h" #include "libANGLE/Surface.h" +#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/renderergl_utils.h" #include "libANGLE/renderer/gl/wgl/DXGISwapChainWindowSurfaceWGL.h" #include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" @@ -19,6 +20,8 @@ #include "libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h" #include "libANGLE/renderer/gl/wgl/wgl_utils.h" +#include "platform/Platform.h" + #include <EGL/eglext.h> #include <string> #include <sstream> @@ -59,6 +62,7 @@ DisplayWGL::DisplayWGL() mOpenGLModule(nullptr), mFunctionsWGL(nullptr), mFunctionsGL(nullptr), + mHasRobustness(false), mWindowClass(0), mWindow(nullptr), mDeviceContext(nullptr), @@ -173,6 +177,9 @@ egl::Error DisplayWGL::initialize(egl::Display *display) // Reinitialize the wgl functions to grab the extensions mFunctionsWGL->initialize(mOpenGLModule, dummyDeviceContext); + bool hasWGLCreateContextRobustness = + mFunctionsWGL->hasExtension("WGL_ARB_create_context_robustness"); + // Destroy the dummy window and context mFunctionsWGL->makeCurrent(dummyDeviceContext, nullptr); mFunctionsWGL->deleteContext(dummyWGLContext); @@ -259,6 +266,12 @@ egl::Error DisplayWGL::initialize(egl::Display *display) std::vector<int> contextCreationAttributes; + if (hasWGLCreateContextRobustness) + { + contextCreationAttributes.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); + contextCreationAttributes.push_back(WGL_LOSE_CONTEXT_ON_RESET_ARB); + } + // Don't request a specific version unless the user wants one. WGL will return the highest version // that the driver supports if no version is requested. EGLint requestedMajorVersion = static_cast<EGLint>( @@ -329,6 +342,14 @@ egl::Error DisplayWGL::initialize(egl::Display *display) mFunctionsGL = new FunctionsGLWindows(mOpenGLModule, mFunctionsWGL->getProcAddress); mFunctionsGL->initialize(); + mHasRobustness = mFunctionsGL->getGraphicsResetStatus != nullptr; + if (hasWGLCreateContextRobustness != mHasRobustness) + { + ANGLEPlatformCurrent()->logWarning( + "WGL_ARB_create_context_robustness exists but unable to OpenGL context with " + "robustness."); + } + // Intel OpenGL ES drivers are not currently supported due to bugs in the driver and ANGLE VendorID vendor = GetVendorID(mFunctionsGL); if (requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE && vendor == VENDOR_ID_INTEL) @@ -416,13 +437,13 @@ SurfaceImpl *DisplayWGL::createWindowSurface(const egl::SurfaceState &state, EGLint orientation = static_cast<EGLint>(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); if (mUseDXGISwapChains) { - return new DXGISwapChainWindowSurfaceWGL(state, this->getRenderer(), window, mD3D11Device, + return new DXGISwapChainWindowSurfaceWGL(state, getRenderer(), window, mD3D11Device, mD3D11DeviceHandle, mWGLContext, mDeviceContext, mFunctionsGL, mFunctionsWGL, orientation); } else { - return new WindowSurfaceWGL(state, this->getRenderer(), window, mPixelFormat, mWGLContext, + return new WindowSurfaceWGL(state, getRenderer(), window, mPixelFormat, mWGLContext, mFunctionsWGL, orientation); } } @@ -437,9 +458,8 @@ SurfaceImpl *DisplayWGL::createPbufferSurface(const egl::SurfaceState &state, EGLenum textureFormat = static_cast<EGLenum>(attribs.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE)); EGLenum textureTarget = static_cast<EGLenum>(attribs.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE)); - return new PbufferSurfaceWGL(state, this->getRenderer(), width, height, textureFormat, - textureTarget, largest, mPixelFormat, mDeviceContext, mWGLContext, - mFunctionsWGL); + return new PbufferSurfaceWGL(state, getRenderer(), width, height, textureFormat, textureTarget, + largest, mPixelFormat, mDeviceContext, mWGLContext, mFunctionsWGL); } SurfaceImpl *DisplayWGL::createPbufferFromClientBuffer(const egl::SurfaceState &state, @@ -541,21 +561,18 @@ egl::ConfigSet DisplayWGL::generateConfigs() return configs; } -bool DisplayWGL::isDeviceLost() const -{ - //UNIMPLEMENTED(); - return false; -} - bool DisplayWGL::testDeviceLost() { - //UNIMPLEMENTED(); + if (mHasRobustness) + { + return getRenderer()->getResetStatus() != GL_NO_ERROR; + } + return false; } egl::Error DisplayWGL::restoreLostDevice() { - UNIMPLEMENTED(); return egl::Error(EGL_BAD_DISPLAY); } @@ -625,6 +642,8 @@ void DisplayWGL::generateExtensions(egl::DisplayExtensions *outExtensions) const // prefer to swap with inverted Y. outExtensions->postSubBuffer = mUseDXGISwapChains; outExtensions->surfaceOrientation = mUseDXGISwapChains; + + outExtensions->createContextRobustness = mHasRobustness; } void DisplayWGL::generateCaps(egl::Caps *outCaps) const diff --git a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h index f4c77925e63..7eabe28079f 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/gl/wgl/DisplayWGL.h @@ -46,7 +46,6 @@ class DisplayWGL : public DisplayGL egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; egl::Error restoreLostDevice() override; @@ -79,6 +78,8 @@ class DisplayWGL : public DisplayGL FunctionsWGL *mFunctionsWGL; FunctionsGL *mFunctionsGL; + bool mHasRobustness; + ATOM mWindowClass; HWND mWindow; HDC mDeviceContext; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/imageformats.h b/chromium/third_party/angle/src/libANGLE/renderer/imageformats.h deleted file mode 100644 index efcf0deee6a..00000000000 --- a/chromium/third_party/angle/src/libANGLE/renderer/imageformats.h +++ /dev/null @@ -1,2030 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// imageformats.h: Defines image format types with functions for mip generation -// and copying. - -#ifndef LIBANGLE_RENDERER_IMAGEFORMATS_H_ -#define LIBANGLE_RENDERER_IMAGEFORMATS_H_ - -#include "libANGLE/angletypes.h" - -#include "common/mathutil.h" - -namespace rx -{ - -// Several structures share functionality for reading, writing or mipmapping but the layout -// must match the texture format which the structure represents. If collapsing or typedefing -// structs in this header, make sure the functionality and memory layout is exactly the same. - -struct L8 -{ - unsigned char L; - - static void readColor(gl::ColorF *dst, const L8 *src) - { - const float lum = gl::normalizedToFloat(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = 1.0f; - } - - static void writeColor(L8 *dst, const gl::ColorF *src) - { - dst->L = gl::floatToNormalized<unsigned char>(src->red); - } - - static void average(L8 *dst, const L8 *src1, const L8 *src2) - { - dst->L = gl::average(src1->L, src2->L); - } -}; - -struct R8 -{ - unsigned char R; - - static void readColor(gl::ColorF *dst, const R8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R8 *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - } - - static void writeColor(R8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - } - - static void average(R8 *dst, const R8 *src1, const R8 *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct A8 -{ - unsigned char A; - - static void readColor(gl::ColorF *dst, const A8 *src) - { - dst->red = 0.0f; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void writeColor(A8 *dst, const gl::ColorF *src) - { - dst->A = gl::floatToNormalized<unsigned char>(src->alpha); - } - - static void average(A8 *dst, const A8 *src1, const A8 *src2) - { - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct L8A8 -{ - unsigned char L; - unsigned char A; - - static void readColor(gl::ColorF *dst, const L8A8 *src) - { - const float lum = gl::normalizedToFloat(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void writeColor(L8A8 *dst, const gl::ColorF *src) - { - dst->L = gl::floatToNormalized<unsigned char>(src->red); - dst->A = gl::floatToNormalized<unsigned char>(src->alpha); - } - - static void average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2) - { - *(unsigned short *)dst = - (((*(unsigned short *)src1 ^ *(unsigned short *)src2) & 0xFEFE) >> 1) + - (*(unsigned short *)src1 & *(unsigned short *)src2); - } -}; - -struct A8L8 -{ - unsigned char A; - unsigned char L; - - static void readColor(gl::ColorF *dst, const A8L8 *src) - { - const float lum = gl::normalizedToFloat(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void writeColor(A8L8 *dst, const gl::ColorF *src) - { - dst->L = gl::floatToNormalized<unsigned char>(src->red); - dst->A = gl::floatToNormalized<unsigned char>(src->alpha); - } - - static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) - { - *(unsigned short *)dst = - (((*(unsigned short *)src1 ^ *(unsigned short *)src2) & 0xFEFE) >> 1) + - (*(unsigned short *)src1 & *(unsigned short *)src2); - } -}; - -struct R8G8 -{ - unsigned char R; - unsigned char G; - - static void readColor(gl::ColorF *dst, const R8G8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R8G8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8G8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - dst->G = gl::floatToNormalized<unsigned char>(src->green); - } - - static void writeColor(R8G8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - dst->G = static_cast<unsigned char>(src->green); - } - - static void average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2) - { - *(unsigned short *)dst = - (((*(unsigned short *)src1 ^ *(unsigned short *)src2) & 0xFEFE) >> 1) + - (*(unsigned short *)src1 & *(unsigned short *)src2); - } -}; - -struct R8G8B8 -{ - unsigned char R; - unsigned char G; - unsigned char B; - - static void readColor(gl::ColorF *dst, const R8G8B8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R8G8B8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->G; - dst->alpha = 1; - } - - static void writeColor(R8G8B8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - dst->G = gl::floatToNormalized<unsigned char>(src->green); - dst->B = gl::floatToNormalized<unsigned char>(src->blue); - } - - static void writeColor(R8G8B8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - dst->G = static_cast<unsigned char>(src->green); - dst->B = static_cast<unsigned char>(src->blue); - } - - static void average(R8G8B8 *dst, const R8G8B8 *src1, const R8G8B8 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct B8G8R8 -{ - unsigned char B; - unsigned char G; - unsigned char R; - - static void readColor(gl::ColorF *dst, const B8G8R8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const B8G8R8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->G; - dst->alpha = 1; - } - - static void writeColor(B8G8R8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - dst->G = gl::floatToNormalized<unsigned char>(src->green); - dst->B = gl::floatToNormalized<unsigned char>(src->blue); - } - - static void writeColor(B8G8R8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - dst->G = static_cast<unsigned char>(src->green); - dst->B = static_cast<unsigned char>(src->blue); - } - - static void average(B8G8R8 *dst, const B8G8R8 *src1, const B8G8R8 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R5G6B5 -{ - // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the - // most significant - // bits of the bitfield, and successive component occupying progressively less significant - // locations" - unsigned short RGB; - - static void readColor(gl::ColorF *dst, const R5G6B5 *src) - { - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGB)); - dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->RGB)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGB)); - dst->alpha = 1.0f; - } - - static void writeColor(R5G6B5 *dst, const gl::ColorF *src) - { - dst->RGB = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | - gl::shiftData<6, 5>(gl::floatToNormalized<6, unsigned short>(src->green)) | - gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); - } - - static void average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2) - { - dst->RGB = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGB), - gl::getShiftedData<5, 11>(src2->RGB))) | - gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->RGB), - gl::getShiftedData<6, 5>(src2->RGB))) | - gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGB), - gl::getShiftedData<5, 0>(src2->RGB))); - } -}; - -struct A8R8G8B8 -{ - unsigned char A; - unsigned char R; - unsigned char G; - unsigned char B; - - static void readColor(gl::ColorF *dst, const A8R8G8B8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const A8R8G8B8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(A8R8G8B8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - dst->G = gl::floatToNormalized<unsigned char>(src->green); - dst->B = gl::floatToNormalized<unsigned char>(src->blue); - dst->A = gl::floatToNormalized<unsigned char>(src->alpha); - } - - static void writeColor(A8R8G8B8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - dst->G = static_cast<unsigned char>(src->green); - dst->B = static_cast<unsigned char>(src->blue); - dst->A = static_cast<unsigned char>(src->alpha); - } - - static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) - { - *(unsigned int *)dst = - (((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) + - (*(unsigned int *)src1 & *(unsigned int *)src2); - } -}; - -struct R8G8B8A8 -{ - unsigned char R; - unsigned char G; - unsigned char B; - unsigned char A; - - static void readColor(gl::ColorF *dst, const R8G8B8A8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const R8G8B8A8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R8G8B8A8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - dst->G = gl::floatToNormalized<unsigned char>(src->green); - dst->B = gl::floatToNormalized<unsigned char>(src->blue); - dst->A = gl::floatToNormalized<unsigned char>(src->alpha); - } - - static void writeColor(R8G8B8A8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - dst->G = static_cast<unsigned char>(src->green); - dst->B = static_cast<unsigned char>(src->blue); - dst->A = static_cast<unsigned char>(src->alpha); - } - - static void average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2) - { - *(unsigned int *)dst = - (((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) + - (*(unsigned int *)src1 & *(unsigned int *)src2); - } -}; - -struct B8G8R8A8 -{ - unsigned char B; - unsigned char G; - unsigned char R; - unsigned char A; - - static void readColor(gl::ColorF *dst, const B8G8R8A8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const B8G8R8A8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(B8G8R8A8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - dst->G = gl::floatToNormalized<unsigned char>(src->green); - dst->B = gl::floatToNormalized<unsigned char>(src->blue); - dst->A = gl::floatToNormalized<unsigned char>(src->alpha); - } - - static void writeColor(B8G8R8A8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - dst->G = static_cast<unsigned char>(src->green); - dst->B = static_cast<unsigned char>(src->blue); - dst->A = static_cast<unsigned char>(src->alpha); - } - - static void average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2) - { - *(unsigned int *)dst = - (((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) + - (*(unsigned int *)src1 & *(unsigned int *)src2); - } -}; - -struct B8G8R8X8 -{ - unsigned char B; - unsigned char G; - unsigned char R; - unsigned char X; - - static void readColor(gl::ColorF *dst, const B8G8R8X8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const B8G8R8X8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(B8G8R8X8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned char>(src->red); - dst->G = gl::floatToNormalized<unsigned char>(src->green); - dst->B = gl::floatToNormalized<unsigned char>(src->blue); - dst->X = 255; - } - - static void writeColor(B8G8R8X8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned char>(src->red); - dst->G = static_cast<unsigned char>(src->green); - dst->B = static_cast<unsigned char>(src->blue); - dst->X = 255; - } - - static void average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2) - { - *(unsigned int *)dst = - (((*(unsigned int *)src1 ^ *(unsigned int *)src2) & 0xFEFEFEFE) >> 1) + - (*(unsigned int *)src1 & *(unsigned int *)src2); - dst->X = 255; - } -}; - -struct A1R5G5B5 -{ - unsigned short ARGB; - - static void readColor(gl::ColorF *dst, const A1R5G5B5 *src) - { - dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->ARGB)); - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->ARGB)); - dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->ARGB)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->ARGB)); - } - - static void writeColor(A1R5G5B5 *dst, const gl::ColorF *src) - { - dst->ARGB = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | - gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->red)) | - gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) | - gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); - } - - static void average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2) - { - dst->ARGB = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->ARGB), - gl::getShiftedData<1, 15>(src2->ARGB))) | - gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->ARGB), - gl::getShiftedData<5, 10>(src2->ARGB))) | - gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->ARGB), - gl::getShiftedData<5, 5>(src2->ARGB))) | - gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->ARGB), - gl::getShiftedData<5, 0>(src2->ARGB))); - } -}; - -struct R5G5B5A1 -{ - // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the - // most significant - // bits of the bitfield, and successive component occupying progressively less significant - // locations" - unsigned short RGBA; - - static void readColor(gl::ColorF *dst, const R5G5B5A1 *src) - { - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGBA)); - dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 6>(src->RGBA)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 1>(src->RGBA)); - dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 0>(src->RGBA)); - } - - static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src) - { - dst->RGBA = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | - gl::shiftData<5, 6>(gl::floatToNormalized<5, unsigned short>(src->green)) | - gl::shiftData<5, 1>(gl::floatToNormalized<5, unsigned short>(src->blue)) | - gl::shiftData<1, 0>(gl::floatToNormalized<1, unsigned short>(src->alpha)); - } - - static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2) - { - dst->RGBA = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGBA), - gl::getShiftedData<5, 11>(src2->RGBA))) | - gl::shiftData<5, 6>(gl::average(gl::getShiftedData<5, 6>(src1->RGBA), - gl::getShiftedData<5, 6>(src2->RGBA))) | - gl::shiftData<5, 1>(gl::average(gl::getShiftedData<5, 1>(src1->RGBA), - gl::getShiftedData<5, 1>(src2->RGBA))) | - gl::shiftData<1, 0>(gl::average(gl::getShiftedData<1, 0>(src1->RGBA), - gl::getShiftedData<1, 0>(src2->RGBA))); - } -}; - -struct R4G4B4A4 -{ - // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the - // most significant - // bits of the bitfield, and successive component occupying progressively less significant - // locations" - unsigned short RGBA; - - static void readColor(gl::ColorF *dst, const R4G4B4A4 *src) - { - dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->RGBA)); - dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->RGBA)); - dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->RGBA)); - dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->RGBA)); - } - - static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src) - { - dst->RGBA = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->red)) | - gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->green)) | - gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->blue)) | - gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->alpha)); - } - - static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2) - { - dst->RGBA = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->RGBA), - gl::getShiftedData<4, 12>(src2->RGBA))) | - gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->RGBA), - gl::getShiftedData<4, 8>(src2->RGBA))) | - gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->RGBA), - gl::getShiftedData<4, 4>(src2->RGBA))) | - gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->RGBA), - gl::getShiftedData<4, 0>(src2->RGBA))); - } -}; - -struct A4R4G4B4 -{ - unsigned short ARGB; - - static void readColor(gl::ColorF *dst, const A4R4G4B4 *src) - { - dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->ARGB)); - dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->ARGB)); - dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->ARGB)); - dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->ARGB)); - } - - static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src) - { - dst->ARGB = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->alpha)) | - gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->red)) | - gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->green)) | - gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->blue)); - } - - static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2) - { - dst->ARGB = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->ARGB), - gl::getShiftedData<4, 12>(src2->ARGB))) | - gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->ARGB), - gl::getShiftedData<4, 8>(src2->ARGB))) | - gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->ARGB), - gl::getShiftedData<4, 4>(src2->ARGB))) | - gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->ARGB), - gl::getShiftedData<4, 0>(src2->ARGB))); - } -}; - -struct R16 -{ - unsigned short R; - - static void readColor(gl::ColorF *dst, const R16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R16 *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned short>(src->red); - } - - static void writeColor(R16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned short>(src->red); - } - - static void average(R16 *dst, const R16 *src1, const R16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R16G16 -{ - unsigned short R; - unsigned short G; - - static void readColor(gl::ColorF *dst, const R16G16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R16G16 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16G16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned short>(src->red); - dst->G = gl::floatToNormalized<unsigned short>(src->green); - } - - static void writeColor(R16G16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned short>(src->red); - dst->G = static_cast<unsigned short>(src->green); - } - - static void average(R16G16 *dst, const R16G16 *src1, const R16G16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R16G16B16 -{ - unsigned short R; - unsigned short G; - unsigned short B; - - static void readColor(gl::ColorF *dst, const R16G16B16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R16G16B16 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R16G16B16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned short>(src->red); - dst->G = gl::floatToNormalized<unsigned short>(src->green); - dst->B = gl::floatToNormalized<unsigned short>(src->blue); - } - - static void writeColor(R16G16B16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned short>(src->red); - dst->G = static_cast<unsigned short>(src->green); - dst->B = static_cast<unsigned short>(src->blue); - } - - static void average(R16G16B16 *dst, const R16G16B16 *src1, const R16G16B16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R16G16B16A16 -{ - unsigned short R; - unsigned short G; - unsigned short B; - unsigned short A; - - static void readColor(gl::ColorF *dst, const R16G16B16A16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const R16G16B16A16 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R16G16B16A16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned short>(src->red); - dst->G = gl::floatToNormalized<unsigned short>(src->green); - dst->B = gl::floatToNormalized<unsigned short>(src->blue); - dst->A = gl::floatToNormalized<unsigned short>(src->alpha); - } - - static void writeColor(R16G16B16A16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned short>(src->red); - dst->G = static_cast<unsigned short>(src->green); - dst->B = static_cast<unsigned short>(src->blue); - dst->A = static_cast<unsigned short>(src->alpha); - } - - static void average(R16G16B16A16 *dst, const R16G16B16A16 *src1, const R16G16B16A16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32 -{ - unsigned int R; - - static void readColor(gl::ColorF *dst, const R32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R32 *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned int>(src->red); - } - - static void writeColor(R32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned int>(src->red); - } - - static void average(R32 *dst, const R32 *src1, const R32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R32G32 -{ - unsigned int R; - unsigned int G; - - static void readColor(gl::ColorF *dst, const R32G32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R32G32 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32G32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned int>(src->red); - dst->G = gl::floatToNormalized<unsigned int>(src->green); - } - - static void writeColor(R32G32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned int>(src->red); - dst->G = static_cast<unsigned int>(src->green); - } - - static void average(R32G32 *dst, const R32G32 *src1, const R32G32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R32G32B32 -{ - unsigned int R; - unsigned int G; - unsigned int B; - - static void readColor(gl::ColorF *dst, const R32G32B32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R32G32B32 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R32G32B32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned int>(src->red); - dst->G = gl::floatToNormalized<unsigned int>(src->green); - dst->B = gl::floatToNormalized<unsigned int>(src->blue); - } - - static void writeColor(R32G32B32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned int>(src->red); - dst->G = static_cast<unsigned int>(src->green); - dst->B = static_cast<unsigned int>(src->blue); - } - - static void average(R32G32B32 *dst, const R32G32B32 *src1, const R32G32B32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R32G32B32A32 -{ - unsigned int R; - unsigned int G; - unsigned int B; - unsigned int A; - - static void readColor(gl::ColorF *dst, const R32G32B32A32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const R32G32B32A32 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R32G32B32A32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<unsigned int>(src->red); - dst->G = gl::floatToNormalized<unsigned int>(src->green); - dst->B = gl::floatToNormalized<unsigned int>(src->blue); - dst->A = gl::floatToNormalized<unsigned int>(src->alpha); - } - - static void writeColor(R32G32B32A32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned int>(src->red); - dst->G = static_cast<unsigned int>(src->green); - dst->B = static_cast<unsigned int>(src->blue); - dst->A = static_cast<unsigned int>(src->alpha); - } - - static void average(R32G32B32A32 *dst, const R32G32B32A32 *src1, const R32G32B32A32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R8S -{ - char R; - - static void readColor(gl::ColorF *dst, const R8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R8S *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<char>(src->red); - } - - static void writeColor(R8S *dst, const gl::ColorI *src) - { - dst->R = static_cast<char>(src->red); - } - - static void average(R8S *dst, const R8S *src1, const R8S *src2) - { - dst->R = static_cast<char>(gl::average(src1->R, src2->R)); - } -}; - -struct R8G8S -{ - char R; - char G; - - static void readColor(gl::ColorF *dst, const R8G8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R8G8S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8G8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<char>(src->red); - dst->G = gl::floatToNormalized<char>(src->green); - } - - static void writeColor(R8G8S *dst, const gl::ColorI *src) - { - dst->R = static_cast<char>(src->red); - dst->G = static_cast<char>(src->green); - } - - static void average(R8G8S *dst, const R8G8S *src1, const R8G8S *src2) - { - dst->R = static_cast<char>(gl::average(src1->R, src2->R)); - dst->G = static_cast<char>(gl::average(src1->G, src2->G)); - } -}; - -struct R8G8B8S -{ - char R; - char G; - char B; - - static void readColor(gl::ColorF *dst, const R8G8B8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R8G8B8S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R8G8B8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<char>(src->red); - dst->G = gl::floatToNormalized<char>(src->green); - dst->B = gl::floatToNormalized<char>(src->blue); - } - - static void writeColor(R8G8B8S *dst, const gl::ColorI *src) - { - dst->R = static_cast<char>(src->red); - dst->G = static_cast<char>(src->green); - dst->B = static_cast<char>(src->blue); - } - - static void average(R8G8B8S *dst, const R8G8B8S *src1, const R8G8B8S *src2) - { - dst->R = static_cast<char>(gl::average(src1->R, src2->R)); - dst->G = static_cast<char>(gl::average(src1->G, src2->G)); - dst->B = static_cast<char>(gl::average(src1->B, src2->B)); - } -}; - -struct R8G8B8A8S -{ - char R; - char G; - char B; - char A; - - static void readColor(gl::ColorF *dst, const R8G8B8A8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorI *dst, const R8G8B8A8S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R8G8B8A8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<char>(src->red); - dst->G = gl::floatToNormalized<char>(src->green); - dst->B = gl::floatToNormalized<char>(src->blue); - dst->A = gl::floatToNormalized<char>(src->alpha); - } - - static void writeColor(R8G8B8A8S *dst, const gl::ColorI *src) - { - dst->R = static_cast<char>(src->red); - dst->G = static_cast<char>(src->green); - dst->B = static_cast<char>(src->blue); - dst->A = static_cast<char>(src->alpha); - } - - static void average(R8G8B8A8S *dst, const R8G8B8A8S *src1, const R8G8B8A8S *src2) - { - dst->R = static_cast<char>(gl::average(src1->R, src2->R)); - dst->G = static_cast<char>(gl::average(src1->G, src2->G)); - dst->B = static_cast<char>(gl::average(src1->B, src2->B)); - dst->A = static_cast<char>(gl::average(src1->A, src2->A)); - } -}; - -struct R16S -{ - short R; - - static void readColor(gl::ColorF *dst, const R16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R16S *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<short>(src->red); - } - - static void writeColor(R16S *dst, const gl::ColorI *src) - { - dst->R = static_cast<short>(src->red); - } - - static void average(R16S *dst, const R16S *src1, const R16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R16G16S -{ - short R; - short G; - - static void readColor(gl::ColorF *dst, const R16G16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R16G16S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16G16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<short>(src->red); - dst->G = gl::floatToNormalized<short>(src->green); - } - - static void writeColor(R16G16S *dst, const gl::ColorI *src) - { - dst->R = static_cast<short>(src->red); - dst->G = static_cast<short>(src->green); - } - - static void average(R16G16S *dst, const R16G16S *src1, const R16G16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R16G16B16S -{ - short R; - short G; - short B; - - static void readColor(gl::ColorF *dst, const R16G16B16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R16G16B16S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R16G16B16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<short>(src->red); - dst->G = gl::floatToNormalized<short>(src->green); - dst->B = gl::floatToNormalized<short>(src->blue); - } - - static void writeColor(R16G16B16S *dst, const gl::ColorI *src) - { - dst->R = static_cast<short>(src->red); - dst->G = static_cast<short>(src->green); - dst->B = static_cast<short>(src->blue); - } - - static void average(R16G16B16S *dst, const R16G16B16S *src1, const R16G16B16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R16G16B16A16S -{ - short R; - short G; - short B; - short A; - - static void readColor(gl::ColorF *dst, const R16G16B16A16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorI *dst, const R16G16B16A16S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R16G16B16A16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<short>(src->red); - dst->G = gl::floatToNormalized<short>(src->green); - dst->B = gl::floatToNormalized<short>(src->blue); - dst->A = gl::floatToNormalized<short>(src->alpha); - } - - static void writeColor(R16G16B16A16S *dst, const gl::ColorI *src) - { - dst->R = static_cast<short>(src->red); - dst->G = static_cast<short>(src->green); - dst->B = static_cast<short>(src->blue); - dst->A = static_cast<short>(src->alpha); - } - - static void average(R16G16B16A16S *dst, const R16G16B16A16S *src1, const R16G16B16A16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32S -{ - int R; - - static void readColor(gl::ColorF *dst, const R32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R32S *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<int>(src->red); - } - - static void writeColor(R32S *dst, const gl::ColorI *src) - { - dst->R = static_cast<int>(src->red); - } - - static void average(R32S *dst, const R32S *src1, const R32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R32G32S -{ - int R; - int G; - - static void readColor(gl::ColorF *dst, const R32G32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R32G32S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32G32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<int>(src->red); - dst->G = gl::floatToNormalized<int>(src->green); - } - - static void writeColor(R32G32S *dst, const gl::ColorI *src) - { - dst->R = static_cast<int>(src->red); - dst->G = static_cast<int>(src->green); - } - - static void average(R32G32S *dst, const R32G32S *src1, const R32G32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R32G32B32S -{ - int R; - int G; - int B; - - static void readColor(gl::ColorF *dst, const R32G32B32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R32G32B32S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R32G32B32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<int>(src->red); - dst->G = gl::floatToNormalized<int>(src->green); - dst->B = gl::floatToNormalized<int>(src->blue); - } - - static void writeColor(R32G32B32S *dst, const gl::ColorI *src) - { - dst->R = static_cast<int>(src->red); - dst->G = static_cast<int>(src->green); - dst->B = static_cast<int>(src->blue); - } - - static void average(R32G32B32S *dst, const R32G32B32S *src1, const R32G32B32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R32G32B32A32S -{ - int R; - int G; - int B; - int A; - - static void readColor(gl::ColorF *dst, const R32G32B32A32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorI *dst, const R32G32B32A32S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R32G32B32A32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<int>(src->red); - dst->G = gl::floatToNormalized<int>(src->green); - dst->B = gl::floatToNormalized<int>(src->blue); - dst->A = gl::floatToNormalized<int>(src->alpha); - } - - static void writeColor(R32G32B32A32S *dst, const gl::ColorI *src) - { - dst->R = static_cast<int>(src->red); - dst->G = static_cast<int>(src->green); - dst->B = static_cast<int>(src->blue); - dst->A = static_cast<int>(src->alpha); - } - - static void average(R32G32B32A32S *dst, const R32G32B32A32S *src1, const R32G32B32A32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct A16B16G16R16F -{ - unsigned short A; - unsigned short R; - unsigned short G; - unsigned short B; - - static void readColor(gl::ColorF *dst, const A16B16G16R16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = gl::float16ToFloat32(src->B); - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(A16B16G16R16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - dst->B = gl::float32ToFloat16(src->blue); - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - dst->B = gl::averageHalfFloat(src1->B, src2->B); - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct R16G16B16A16F -{ - unsigned short R; - unsigned short G; - unsigned short B; - unsigned short A; - - static void readColor(gl::ColorF *dst, const R16G16B16A16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = gl::float16ToFloat32(src->B); - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(R16G16B16A16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - dst->B = gl::float32ToFloat16(src->blue); - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(R16G16B16A16F *dst, const R16G16B16A16F *src1, const R16G16B16A16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - dst->B = gl::averageHalfFloat(src1->B, src2->B); - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct R16F -{ - unsigned short R; - - static void readColor(gl::ColorF *dst, const R16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - } - - static void average(R16F *dst, const R16F *src1, const R16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - } -}; - -struct A16F -{ - unsigned short A; - - static void readColor(gl::ColorF *dst, const A16F *src) - { - dst->red = 0.0f; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(A16F *dst, const gl::ColorF *src) - { - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(A16F *dst, const A16F *src1, const A16F *src2) - { - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct L16F -{ - unsigned short L; - - static void readColor(gl::ColorF *dst, const L16F *src) - { - float lum = gl::float16ToFloat32(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = 1.0f; - } - - static void writeColor(L16F *dst, const gl::ColorF *src) - { - dst->L = gl::float32ToFloat16(src->red); - } - - static void average(L16F *dst, const L16F *src1, const L16F *src2) - { - dst->L = gl::averageHalfFloat(src1->L, src2->L); - } -}; - -struct L16A16F -{ - unsigned short L; - unsigned short A; - - static void readColor(gl::ColorF *dst, const L16A16F *src) - { - float lum = gl::float16ToFloat32(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(L16A16F *dst, const gl::ColorF *src) - { - dst->L = gl::float32ToFloat16(src->red); - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(L16A16F *dst, const L16A16F *src1, const L16A16F *src2) - { - dst->L = gl::averageHalfFloat(src1->L, src2->L); - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct R16G16F -{ - unsigned short R; - unsigned short G; - - static void readColor(gl::ColorF *dst, const R16G16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R16G16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - } - - static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - } -}; - -struct R16G16B16F -{ - unsigned short R; - unsigned short G; - unsigned short B; - - static void readColor(gl::ColorF *dst, const R16G16B16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = gl::float16ToFloat32(src->B); - dst->alpha = 1.0f; - } - - static void writeColor(R16G16B16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - dst->B = gl::float32ToFloat16(src->blue); - } - - static void average(R16G16B16F *dst, const R16G16B16F *src1, const R16G16B16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - dst->B = gl::averageHalfFloat(src1->B, src2->B); - } -}; - -struct A32B32G32R32F -{ - float A; - float R; - float G; - float B; - - static void readColor(gl::ColorF *dst, const A32B32G32R32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(A32B32G32R32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - dst->B = src->blue; - dst->A = src->alpha; - } - - static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32G32B32A32F -{ - float R; - float G; - float B; - float A; - - static void readColor(gl::ColorF *dst, const R32G32B32A32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R32G32B32A32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - dst->B = src->blue; - dst->A = src->alpha; - } - - static void average(R32G32B32A32F *dst, const R32G32B32A32F *src1, const R32G32B32A32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32F -{ - float R; - - static void readColor(gl::ColorF *dst, const R32F *src) - { - dst->red = src->R; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R32F *dst, const gl::ColorF *src) { dst->R = src->red; } - - static void average(R32F *dst, const R32F *src1, const R32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct A32F -{ - float A; - - static void readColor(gl::ColorF *dst, const A32F *src) - { - dst->red = 0.0f; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = src->A; - } - - static void writeColor(A32F *dst, const gl::ColorF *src) { dst->A = src->alpha; } - - static void average(A32F *dst, const A32F *src1, const A32F *src2) - { - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct L32F -{ - float L; - - static void readColor(gl::ColorF *dst, const L32F *src) - { - dst->red = src->L; - dst->green = src->L; - dst->blue = src->L; - dst->alpha = 1.0f; - } - - static void writeColor(L32F *dst, const gl::ColorF *src) - { - dst->L = src->red; - } - - static void average(L32F *dst, const L32F *src1, const L32F *src2) - { - dst->L = gl::average(src1->L, src2->L); - } -}; - -struct L32A32F -{ - float L; - float A; - - static void readColor(gl::ColorF *dst, const L32A32F *src) - { - dst->red = src->L; - dst->green = src->L; - dst->blue = src->L; - dst->alpha = src->A; - } - - static void writeColor(L32A32F *dst, const gl::ColorF *src) - { - dst->L = src->red; - dst->A = src->alpha; - } - - static void average(L32A32F *dst, const L32A32F *src1, const L32A32F *src2) - { - dst->L = gl::average(src1->L, src2->L); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32G32F -{ - float R; - float G; - - static void readColor(gl::ColorF *dst, const R32G32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R32G32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - } - - static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R32G32B32F -{ - float R; - float G; - float B; - - static void readColor(gl::ColorF *dst, const R32G32B32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1.0f; - } - - static void writeColor(R32G32B32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - dst->B = src->blue; - } - - static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R10G10B10A2 -{ - unsigned int R : 10; - unsigned int G : 10; - unsigned int B : 10; - unsigned int A : 2; - - static void readColor(gl::ColorF *dst, const R10G10B10A2 *src) - { - dst->red = gl::normalizedToFloat<10>(src->R); - dst->green = gl::normalizedToFloat<10>(src->G); - dst->blue = gl::normalizedToFloat<10>(src->B); - dst->alpha = gl::normalizedToFloat<2>(src->A); - } - - static void readColor(gl::ColorUI *dst, const R10G10B10A2 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R10G10B10A2 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<10, unsigned int>(src->red); - dst->G = gl::floatToNormalized<10, unsigned int>(src->green); - dst->B = gl::floatToNormalized<10, unsigned int>(src->blue); - dst->A = gl::floatToNormalized<2, unsigned int>(src->alpha); - } - - static void writeColor(R10G10B10A2 *dst, const gl::ColorUI *src) - { - dst->R = static_cast<unsigned int>(src->red); - dst->G = static_cast<unsigned int>(src->green); - dst->B = static_cast<unsigned int>(src->blue); - dst->A = static_cast<unsigned int>(src->alpha); - } - - static void average(R10G10B10A2 *dst, const R10G10B10A2 *src1, const R10G10B10A2 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R9G9B9E5 -{ - unsigned int R : 9; - unsigned int G : 9; - unsigned int B : 9; - unsigned int E : 5; - - static void readColor(gl::ColorF *dst, const R9G9B9E5 *src) - { - gl::convert999E5toRGBFloats(gl::bitCast<unsigned int>(*src), &dst->red, &dst->green, - &dst->blue); - dst->alpha = 1.0f; - } - - static void writeColor(R9G9B9E5 *dst, const gl::ColorF *src) - { - *reinterpret_cast<unsigned int *>(dst) = - gl::convertRGBFloatsTo999E5(src->red, src->green, src->blue); - } - - static void average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2) - { - float r1, g1, b1; - gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int *>(src1), &r1, &g1, &b1); - - float r2, g2, b2; - gl::convert999E5toRGBFloats(*reinterpret_cast<const unsigned int *>(src2), &r2, &g2, &b2); - - *reinterpret_cast<unsigned int *>(dst) = gl::convertRGBFloatsTo999E5( - gl::average(r1, r2), gl::average(g1, g2), gl::average(b1, b2)); - } -}; - -struct R11G11B10F -{ - unsigned int R : 11; - unsigned int G : 11; - unsigned int B : 10; - - static void readColor(gl::ColorF *dst, const R11G11B10F *src) - { - dst->red = gl::float11ToFloat32(src->R); - dst->green = gl::float11ToFloat32(src->G); - dst->blue = gl::float10ToFloat32(src->B); - dst->alpha = 1.0f; - } - - static void writeColor(R11G11B10F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat11(src->red); - dst->G = gl::float32ToFloat11(src->green); - dst->B = gl::float32ToFloat10(src->blue); - } - - static void average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B10F *src2) - { - dst->R = gl::averageFloat11(src1->R, src2->R); - dst->G = gl::averageFloat11(src1->G, src2->G); - dst->B = gl::averageFloat10(src1->B, src2->B); - } -}; -} // namespace rx - -#endif // LIBANGLE_RENDERER_IMAGEFORMATS_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/load_functions_data.json b/chromium/third_party/angle/src/libANGLE/renderer/load_functions_data.json new file mode 100644 index 00000000000..8145704d601 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/load_functions_data.json @@ -0,0 +1,562 @@ +{ + "GL_RG8_SNORM": { + "R8G8_SNORM": { + "GL_BYTE": "LoadToNative<GLbyte, 2>" + } + }, + "GL_SRGB8": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4<GLubyte, 0xFF>" + } + }, + "GL_RGBA8I": { + "R8G8B8A8_SINT": { + "GL_BYTE": "LoadToNative<GLbyte, 4>" + } + }, + "GL_R8_SNORM": { + "R8_SNORM": { + "GL_BYTE": "LoadToNative<GLbyte, 1>" + } + }, + "GL_RGBA8_SNORM": { + "R8G8B8A8_SNORM": { + "GL_BYTE": "LoadToNative<GLbyte, 4>" + } + }, + "GL_R16I": { + "R16_SINT": { + "GL_SHORT": "LoadToNative<GLshort, 1>" + } + }, + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGBA8ToSRGBA8" + } + }, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC2RGB8A1ToRGBA8" + } + }, + "GL_RGB32UI": { + "R32G32B32A32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative3To4<GLuint, 0x00000001>" + } + }, + "GL_ALPHA32F_EXT": { + "NONE": { + "GL_FLOAT": "LoadA32FToRGBA32F" + } + }, + "GL_R16UI": { + "R16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative<GLushort, 1>" + } + }, + "GL_RGB9_E5": { + "R9G9B9E5_SHAREDEXP": { + "GL_HALF_FLOAT": "LoadRGB16FToRGB9E5", + "GL_UNSIGNED_INT_5_9_9_9_REV": "LoadToNative<GLuint, 1>", + "GL_FLOAT": "LoadRGB32FToRGB9E5", + "GL_HALF_FLOAT_OES": "LoadRGB16FToRGB9E5" + } + }, + "GL_COMPRESSED_R11_EAC": { + "R8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadEACR11ToR8" + } + }, + "GL_RGBA32UI": { + "R32G32B32A32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative<GLuint, 4>" + } + }, + "GL_RG8UI": { + "R8G8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 2>" + } + }, + "GL_LUMINANCE32F_EXT": { + "NONE": { + "GL_FLOAT": "LoadL32FToRGBA32F" + } + }, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGB8A1ToRGBA8" + } + }, + "GL_R16F": { + "R16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative<GLhalf, 1>", + "GL_FLOAT": "Load32FTo16F<1>", + "GL_HALF_FLOAT_OES": "LoadToNative<GLhalf, 1>" + } + }, + "GL_RGBA8UI": { + "R8G8B8A8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>" + } + }, + "GL_BGRA4_ANGLEX": { + "NONE": { + "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": "LoadRGBA4ToRGBA8", + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>" + } + }, + "GL_RGBA16F": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative<GLhalf, 4>", + "GL_FLOAT": "Load32FTo16F<4>", + "GL_HALF_FLOAT_OES": "LoadToNative<GLhalf, 4>" + } + }, + "GL_LUMINANCE8_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadL8ToRGBA8" + } + }, + "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 16>" + } + }, + "GL_RGB": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction", + "GL_UNSIGNED_SHORT_5_6_5": "UnreachableLoadFunction" + } + }, + "GL_RGB5_A1": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadRGB10A2ToRGBA8", + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>", + "GL_UNSIGNED_SHORT_5_5_5_1": "LoadRGB5A1ToRGBA8" + }, + "B5G5R5A1_UNORM": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadRGB10A2ToBGR5A1", + "GL_UNSIGNED_BYTE": "LoadRGBA8ToBGR5A1", + "GL_UNSIGNED_SHORT_5_5_5_1": "LoadRGB5A1ToA1RGB5" + } + }, + "GL_RGB16UI": { + "R16G16B16A16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative3To4<GLushort, 0x0001>" + } + }, + "GL_BGRA_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + } + }, + "GL_COMPRESSED_RGB8_ETC2": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC2RGB8ToRGBA8" + } + }, + "GL_RGBA32F": { + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadToNative<GLfloat, 4>" + } + }, + "GL_RGBA32I": { + "R32G32B32A32_SINT": { + "GL_INT": "LoadToNative<GLint, 4>" + } + }, + "GL_LUMINANCE8_ALPHA8_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadLA8ToRGBA8" + } + }, + "GL_RG8": { + "R8G8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 2>" + } + }, + "GL_RGB10_A2": { + "R10G10B10A2_UNORM": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadToNative<GLuint, 1>" + } + }, + "GL_COMPRESSED_SIGNED_RG11_EAC": { + "R8G8_SNORM": { + "GL_UNSIGNED_BYTE": "LoadEACRG11SToRG8" + } + }, + "GL_DEPTH_COMPONENT16": { + "D16_UNORM": { + "GL_UNSIGNED_INT": "LoadR32ToR16", + "GL_UNSIGNED_SHORT": "LoadToNative<GLushort, 1>" + } + }, + "GL_RGB32I": { + "R32G32B32A32_SINT": { + "GL_INT": "LoadToNative3To4<GLint, 0x00000001>" + } + }, + "GL_R8": { + "R8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 1>" + } + }, + "GL_RGB32F": { + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadToNative3To4<GLfloat, gl::Float32One>" + } + }, + "GL_R11F_G11F_B10F": { + "R11G11B10_FLOAT": { + "GL_UNSIGNED_INT_10F_11F_11F_REV": "LoadToNative<GLuint, 1>", + "GL_HALF_FLOAT": "LoadRGB16FToRG11B10F", + "GL_FLOAT": "LoadRGB32FToRG11B10F", + "GL_HALF_FLOAT_OES": "LoadRGB16FToRG11B10F" + } + }, + "GL_RGB8": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4<GLubyte, 0xFF>" + } + }, + "GL_LUMINANCE_ALPHA": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadLA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadLA16FToRGBA16F" + }, + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + }, + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadLA32FToRGBA32F" + } + }, + "GL_RGBA16I": { + "R16G16B16A16_SINT": { + "GL_SHORT": "LoadToNative<GLshort, 4>" + } + }, + "GL_R8I": { + "R8_SINT": { + "GL_BYTE": "LoadToNative<GLbyte, 1>" + } + }, + "GL_RGB8_SNORM": { + "R8G8B8A8_SNORM": { + "GL_BYTE": "LoadToNative3To4<GLbyte, 0x7F>" + } + }, + "GL_RG32F": { + "R32G32_FLOAT": { + "GL_FLOAT": "LoadToNative<GLfloat, 2>" + } + }, + "GL_DEPTH_COMPONENT32F": { + "D32_FLOAT": { + "GL_FLOAT": "LoadD32FToD32F" + } + }, + "GL_RG32I": { + "R32G32_SINT": { + "GL_INT": "LoadToNative<GLint, 2>" + } + }, + "GL_ALPHA8_EXT": { + "A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 1>" + }, + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadA8ToRGBA8" + } + }, + "GL_RG32UI": { + "R32G32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative<GLuint, 2>" + } + }, + "GL_RGBA16UI": { + "R16G16B16A16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative<GLushort, 4>" + } + }, + "GL_COMPRESSED_RGBA8_ETC2_EAC": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC2RGBA8ToRGBA8" + } + }, + "GL_RGB8I": { + "R8G8B8A8_SINT": { + "GL_BYTE": "LoadToNative3To4<GLbyte, 0x01>" + } + }, + "GL_COMPRESSED_SRGB8_ETC2": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGB8ToRGBA8" + } + }, + "GL_DEPTH32F_STENCIL8": { + "D32_FLOAT_S8X24_UINT": { + "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": "LoadD32FS8X24ToD32FS8X24" + } + }, + "GL_RG8I": { + "R8G8_SINT": { + "GL_BYTE": "LoadToNative<GLbyte, 2>" + } + }, + "GL_R32UI": { + "R32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative<GLuint, 1>" + } + }, + "GL_BGR5_A1_ANGLEX": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>", + "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": "LoadRGB5A1ToRGBA8" + } + }, + "GL_BGR565_ANGLEX": { + "B5G6R5_UNORM": { + "GL_UNSIGNED_SHORT_5_6_5": "LoadRGB565ToBGR565", + "GL_UNSIGNED_BYTE": "LoadToNative<GLushort, 1>" + } + }, + "GL_COMPRESSED_RG11_EAC": { + "R8G8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadEACRG11ToRG8" + } + }, + "GL_SRGB8_ALPHA8": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>" + } + }, + "GL_LUMINANCE_ALPHA16F_EXT": { + "NONE": { + "GL_HALF_FLOAT": "LoadLA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadLA16FToRGBA16F" + } + }, + "GL_RGBA": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction", + "GL_UNSIGNED_SHORT_4_4_4_4": "UnreachableLoadFunction", + "GL_UNSIGNED_SHORT_5_5_5_1": "UnreachableLoadFunction" + } + }, + "GL_DEPTH24_STENCIL8": { + "D24_UNORM_S8_UINT": { + "GL_UNSIGNED_INT_24_8": "LoadR32ToR24G8" + } + }, + "GL_RGB16I": { + "R16G16B16A16_SINT": { + "GL_SHORT": "LoadToNative3To4<GLshort, 0x0001>" + } + }, + "GL_R8UI": { + "R8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 1>" + } + }, + "GL_ALPHA": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadA16FToRGBA16F" + }, + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + }, + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadA32FToRGBA32F" + } + }, + "GL_RGB16F": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative3To4<GLhalf, gl::Float16One>", + "GL_FLOAT": "LoadRGB32FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadToNative3To4<GLhalf, gl::Float16One>" + } + }, + "GL_COMPRESSED_SIGNED_R11_EAC": { + "R8_SNORM": { + "GL_UNSIGNED_BYTE": "LoadEACR11SToR8" + } + }, + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 8>" + } + }, + "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 8>" + } + }, + "GL_STENCIL_INDEX8": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnimplementedLoadFunction" + } + }, + "GL_LUMINANCE_ALPHA32F_EXT": { + "NONE": { + "GL_FLOAT": "LoadLA32FToRGBA32F" + } + }, + "GL_RGB8UI": { + "R8G8B8A8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4<GLubyte, 0x01>" + } + }, + "GL_DEPTH_COMPONENT24": { + "D24_UNORM_S8_UINT": { + "GL_UNSIGNED_INT": "LoadR32ToR24G8" + } + }, + "GL_R32I": { + "R32_SINT": { + "GL_INT": "LoadToNative<GLint, 1>" + } + }, + "GL_DEPTH_COMPONENT32_OES": { + "NONE": { + "GL_UNSIGNED_INT": "LoadR32ToR24G8" + } + }, + "GL_R32F": { + "R32_FLOAT": { + "GL_FLOAT": "LoadToNative<GLfloat, 1>" + } + }, + "GL_RG16F": { + "R16G16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative<GLhalf, 2>", + "GL_FLOAT": "Load32FTo16F<2>", + "GL_HALF_FLOAT_OES": "LoadToNative<GLhalf, 2>" + } + }, + "GL_RGB565": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4<GLubyte, 0xFF>", + "GL_UNSIGNED_SHORT_5_6_5": "LoadR5G6B5ToRGBA8" + }, + "B5G6R5_UNORM": { + "GL_UNSIGNED_BYTE": "LoadRGB8ToBGR565", + "GL_UNSIGNED_SHORT_5_6_5": "LoadToNative<GLushort, 1>" + } + }, + "GL_LUMINANCE16F_EXT": { + "NONE": { + "GL_HALF_FLOAT": "LoadL16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadL16FToRGBA16F" + } + }, + "GL_RG16UI": { + "R16G16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative<GLushort, 2>" + } + }, + "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 16>" + } + }, + "GL_RG16I": { + "R16G16_SINT": { + "GL_SHORT": "LoadToNative<GLshort, 2>" + } + }, + "GL_BGRA8_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>" + } + }, + "GL_ALPHA16F_EXT": { + "NONE": { + "GL_HALF_FLOAT": "LoadA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadA16FToRGBA16F" + } + }, + "GL_RGBA4": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>", + "GL_UNSIGNED_SHORT_4_4_4_4": "LoadRGBA4ToRGBA8" + }, + "B4G4R4A4_UNORM": { + "GL_UNSIGNED_BYTE": "LoadRGBA8ToBGRA4", + "GL_UNSIGNED_SHORT_4_4_4_4": "LoadRGBA4ToARGB4" + } + }, + "GL_RGBA8": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative<GLubyte, 4>" + } + }, + "GL_LUMINANCE": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadL16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadL16FToRGBA16F" + }, + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + }, + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadL32FToRGBA32F" + } + }, + "GL_RGB10_A2UI": { + "R10G10B10A2_UINT": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadToNative<GLuint, 1>" + } + }, + "GL_ETC1_RGB8_OES": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC1RGB8ToRGBA8" + } + }, + "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": { + "BC1_RGB_UNORM_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadETC1RGB8ToBC1" + } + }, + "GL_R16_EXT": { + "R16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative<GLushort, 1>" + } + }, + "GL_RG16_EXT": { + "R16G16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative<GLushort, 2>" + } + }, + "GL_RGB16_EXT": { + "R16G16B16A16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative3To4<GLushort, 0xFFFF>" + } + }, + "GL_RGBA16_EXT": { + "R16G16B16A16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative<GLushort, 4>" + } + }, + "GL_R16_SNORM_EXT": { + "R16_SNORM": { + "GL_SHORT": "LoadToNative<GLushort, 1>" + } + }, + "GL_RG16_SNORM_EXT": { + "R16G16_SNORM": { + "GL_SHORT": "LoadToNative<GLushort, 2>" + } + }, + "GL_RGB16_SNORM_EXT": { + "R16G16B16A16_SNORM": { + "GL_SHORT": "LoadToNative3To4<GLushort, 0x7FFF>" + } + }, + "GL_RGBA16_SNORM_EXT": { + "R16G16B16A16_SNORM": { + "GL_SHORT": "LoadToNative<GLushort, 4>" + } + } +} diff --git a/chromium/third_party/angle/src/libANGLE/renderer/load_functions_table.h b/chromium/third_party/angle/src/libANGLE/renderer/load_functions_table.h new file mode 100644 index 00000000000..f3da31c1000 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/load_functions_table.h @@ -0,0 +1,22 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// load_functions_table: +// Contains load functions table depending on internal format and ANGLE format. +// + +#ifndef LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ +#define LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ + +#include "libANGLE/renderer/Format.h" + +namespace angle +{ + +rx::LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, Format::ID angleFormat); + +} // namespace angle + +#endif // LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp b/chromium/third_party/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp new file mode 100644 index 00000000000..c93f87385ff --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp @@ -0,0 +1,2311 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_load_functions_table.py using data from load_functions_data.json +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// load_functions_table: +// Contains the GetLoadFunctionsMap for texture_format_util.h +// + +#include "libANGLE/renderer/load_functions_table.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +using namespace rx; + +namespace angle +{ + +namespace +{ + +// ES3 image loading functions vary based on: +// - the GL internal format (supplied to glTex*Image*D) +// - the GL data type given (supplied to glTex*Image*D) +// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D +// device's capabilities) +// This map type determines which loading function to use, based on these three parameters. +// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. +void UnimplementedLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + UNIMPLEMENTED(); +} + +void UnreachableLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + UNREACHABLE(); +} + +LoadImageFunctionInfo ALPHA_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA8_EXT_to_A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA8_EXT_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGR565_ANGLEX_to_B5G6R5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadRGB565ToBGR565, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGR5_A1_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA4_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA8_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11ToR8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R8G8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11ToRG8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_ETC2_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA8_ETC2_EAC_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGBA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT3_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT5_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R8_SNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11SToR8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R8G8_SNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11SToRG8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGBA8ToSRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ETC2_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH24_STENCIL8_to_D24_UNORM_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_24_8: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH32F_STENCIL8_to_D32_FLOAT_S8X24_UINT(GLenum type) +{ + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return LoadImageFunctionInfo(LoadD32FS8X24ToD32FS8X24, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT16_to_D16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR16, true); + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT24_to_D24_UNORM_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT32F_to_D32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadD32FToD32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT32_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_LOSSY_DECODE_ANGLE_to_BC1_RGB_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC1RGB8ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC1RGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadLA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadL8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R11F_G11F_B10F_to_R11G11B10_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRG11B10F, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return LoadImageFunctionInfo(LoadToNative<GLuint, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16F_to_R16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<1>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative<GLhalf, 1>, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative<GLhalf, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16I_to_R16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLshort, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16UI_to_R16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_EXT_to_R16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_SNORM_EXT_to_R16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32F_to_R32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative<GLfloat, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32I_to_R32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative<GLint, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32UI_to_R32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative<GLuint, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_to_R8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8I_to_R8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLbyte, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8UI_to_R8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_SNORM_to_R8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLbyte, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16F_to_R16G16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<2>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative<GLhalf, 2>, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative<GLhalf, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16I_to_R16G16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLshort, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16UI_to_R16G16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_EXT_to_R16G16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_SNORM_EXT_to_R16G16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32F_to_R32G32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative<GLfloat, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32I_to_R32G32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative<GLint, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32UI_to_R32G32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative<GLuint, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_to_R8G8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8I_to_R8G8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLbyte, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8UI_to_R8G8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_SNORM_to_R8G8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLbyte, 2>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2_to_R10G10B10A2_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative<GLuint, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2UI_to_R10G10B10A2_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative<GLuint, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16F_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRGBA16F, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative3To4<GLhalf, gl::Float16One>, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative3To4<GLhalf, gl::Float16One>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16I_to_R16G16B16A16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4<GLshort, 0x0001>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16UI_to_R16G16B16A16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4<GLushort, 0x0001>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_EXT_to_R16G16B16A16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4<GLushort, 0xFFFF>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_SNORM_EXT_to_R16G16B16A16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4<GLushort, 0x7FFF>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32F_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative3To4<GLfloat, gl::Float32One>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32I_to_R32G32B32A32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative3To4<GLint, 0x00000001>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32UI_to_R32G32B32A32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative3To4<GLuint, 0x00000001>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB565_to_B5G6R5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB8ToBGR565, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB565_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4<GLubyte, 0xFF>, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_B5G5R5A1_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToBGR5A1, true); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToBGR5A1, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4<GLubyte, 0xFF>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8I_to_R8G8B8A8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4<GLbyte, 0x01>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8UI_to_R8G8B8A8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4<GLubyte, 0x01>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_SNORM_to_R8G8B8A8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4<GLbyte, 0x7F>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB9_E5_to_R9G9B9E5_SHAREDEXP(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRGB9E5, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + case GL_UNSIGNED_INT_5_9_9_9_REV: + return LoadImageFunctionInfo(LoadToNative<GLuint, 1>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16F_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<4>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative<GLhalf, 4>, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative<GLhalf, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16I_to_R16G16B16A16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLshort, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16UI_to_R16G16B16A16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_EXT_to_R16G16B16A16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_SNORM_EXT_to_R16G16B16A16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative<GLushort, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32F_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative<GLfloat, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32I_to_R32G32B32A32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative<GLint, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32UI_to_R32G32B32A32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative<GLuint, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA4_to_B4G4R4A4_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToBGRA4, true); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(LoadRGBA4ToARGB4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA4_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8I_to_R8G8B8A8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLbyte, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8UI_to_R8G8B8A8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_SNORM_to_R8G8B8A8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLbyte, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRGB8_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4<GLubyte, 0xFF>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRGB8_ALPHA8_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo STENCIL_INDEX8_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnimplementedLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +} // namespace + +LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, Format::ID angleFormat) +{ + // clang-format off + switch (internalFormat) + { + case GL_ALPHA: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return ALPHA_to_R16G16B16A16_FLOAT; + case Format::ID::R32G32B32A32_FLOAT: + return ALPHA_to_R32G32B32A32_FLOAT; + default: + return ALPHA_to_default; + } + } + case GL_ALPHA16F_EXT: + return ALPHA16F_EXT_to_default; + case GL_ALPHA32F_EXT: + return ALPHA32F_EXT_to_default; + case GL_ALPHA8_EXT: + { + switch (angleFormat) + { + case Format::ID::A8_UNORM: + return ALPHA8_EXT_to_A8_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return ALPHA8_EXT_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_BGR565_ANGLEX: + { + switch (angleFormat) + { + case Format::ID::B5G6R5_UNORM: + return BGR565_ANGLEX_to_B5G6R5_UNORM; + default: + break; + } + } + case GL_BGR5_A1_ANGLEX: + return BGR5_A1_ANGLEX_to_default; + case GL_BGRA4_ANGLEX: + return BGRA4_ANGLEX_to_default; + case GL_BGRA8_EXT: + return BGRA8_EXT_to_default; + case GL_BGRA_EXT: + return BGRA_EXT_to_default; + case GL_COMPRESSED_R11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8_UNORM: + return COMPRESSED_R11_EAC_to_R8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RG11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8_UNORM: + return COMPRESSED_RG11_EAC_to_R8G8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGB8_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return COMPRESSED_RGB8_ETC2_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGBA8_ETC2_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA8_ETC2_EAC_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return COMPRESSED_RGBA_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + return COMPRESSED_RGBA_S3TC_DXT3_ANGLE_to_default; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return COMPRESSED_RGBA_S3TC_DXT5_ANGLE_to_default; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return COMPRESSED_RGB_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_SIGNED_R11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8_SNORM: + return COMPRESSED_SIGNED_R11_EAC_to_R8_SNORM; + default: + break; + } + } + case GL_COMPRESSED_SIGNED_RG11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8_SNORM: + return COMPRESSED_SIGNED_RG11_EAC_to_R8G8_SNORM; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ETC2_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_DEPTH24_STENCIL8: + { + switch (angleFormat) + { + case Format::ID::D24_UNORM_S8_UINT: + return DEPTH24_STENCIL8_to_D24_UNORM_S8_UINT; + default: + break; + } + } + case GL_DEPTH32F_STENCIL8: + { + switch (angleFormat) + { + case Format::ID::D32_FLOAT_S8X24_UINT: + return DEPTH32F_STENCIL8_to_D32_FLOAT_S8X24_UINT; + default: + break; + } + } + case GL_DEPTH_COMPONENT16: + { + switch (angleFormat) + { + case Format::ID::D16_UNORM: + return DEPTH_COMPONENT16_to_D16_UNORM; + default: + break; + } + } + case GL_DEPTH_COMPONENT24: + { + switch (angleFormat) + { + case Format::ID::D24_UNORM_S8_UINT: + return DEPTH_COMPONENT24_to_D24_UNORM_S8_UINT; + default: + break; + } + } + case GL_DEPTH_COMPONENT32F: + { + switch (angleFormat) + { + case Format::ID::D32_FLOAT: + return DEPTH_COMPONENT32F_to_D32_FLOAT; + default: + break; + } + } + case GL_DEPTH_COMPONENT32_OES: + return DEPTH_COMPONENT32_OES_to_default; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + { + switch (angleFormat) + { + case Format::ID::BC1_RGB_UNORM_BLOCK: + return ETC1_RGB8_LOSSY_DECODE_ANGLE_to_BC1_RGB_UNORM_BLOCK; + default: + break; + } + } + case GL_ETC1_RGB8_OES: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return ETC1_RGB8_OES_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_LUMINANCE: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return LUMINANCE_to_R16G16B16A16_FLOAT; + case Format::ID::R32G32B32A32_FLOAT: + return LUMINANCE_to_R32G32B32A32_FLOAT; + default: + return LUMINANCE_to_default; + } + } + case GL_LUMINANCE16F_EXT: + return LUMINANCE16F_EXT_to_default; + case GL_LUMINANCE32F_EXT: + return LUMINANCE32F_EXT_to_default; + case GL_LUMINANCE8_ALPHA8_EXT: + return LUMINANCE8_ALPHA8_EXT_to_default; + case GL_LUMINANCE8_EXT: + return LUMINANCE8_EXT_to_default; + case GL_LUMINANCE_ALPHA: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT; + case Format::ID::R32G32B32A32_FLOAT: + return LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT; + default: + return LUMINANCE_ALPHA_to_default; + } + } + case GL_LUMINANCE_ALPHA16F_EXT: + return LUMINANCE_ALPHA16F_EXT_to_default; + case GL_LUMINANCE_ALPHA32F_EXT: + return LUMINANCE_ALPHA32F_EXT_to_default; + case GL_R11F_G11F_B10F: + { + switch (angleFormat) + { + case Format::ID::R11G11B10_FLOAT: + return R11F_G11F_B10F_to_R11G11B10_FLOAT; + default: + break; + } + } + case GL_R16F: + { + switch (angleFormat) + { + case Format::ID::R16_FLOAT: + return R16F_to_R16_FLOAT; + default: + break; + } + } + case GL_R16I: + { + switch (angleFormat) + { + case Format::ID::R16_SINT: + return R16I_to_R16_SINT; + default: + break; + } + } + case GL_R16UI: + { + switch (angleFormat) + { + case Format::ID::R16_UINT: + return R16UI_to_R16_UINT; + default: + break; + } + } + case GL_R16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16_UNORM: + return R16_EXT_to_R16_UNORM; + default: + break; + } + } + case GL_R16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16_SNORM: + return R16_SNORM_EXT_to_R16_SNORM; + default: + break; + } + } + case GL_R32F: + { + switch (angleFormat) + { + case Format::ID::R32_FLOAT: + return R32F_to_R32_FLOAT; + default: + break; + } + } + case GL_R32I: + { + switch (angleFormat) + { + case Format::ID::R32_SINT: + return R32I_to_R32_SINT; + default: + break; + } + } + case GL_R32UI: + { + switch (angleFormat) + { + case Format::ID::R32_UINT: + return R32UI_to_R32_UINT; + default: + break; + } + } + case GL_R8: + { + switch (angleFormat) + { + case Format::ID::R8_UNORM: + return R8_to_R8_UNORM; + default: + break; + } + } + case GL_R8I: + { + switch (angleFormat) + { + case Format::ID::R8_SINT: + return R8I_to_R8_SINT; + default: + break; + } + } + case GL_R8UI: + { + switch (angleFormat) + { + case Format::ID::R8_UINT: + return R8UI_to_R8_UINT; + default: + break; + } + } + case GL_R8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8_SNORM: + return R8_SNORM_to_R8_SNORM; + default: + break; + } + } + case GL_RG16F: + { + switch (angleFormat) + { + case Format::ID::R16G16_FLOAT: + return RG16F_to_R16G16_FLOAT; + default: + break; + } + } + case GL_RG16I: + { + switch (angleFormat) + { + case Format::ID::R16G16_SINT: + return RG16I_to_R16G16_SINT; + default: + break; + } + } + case GL_RG16UI: + { + switch (angleFormat) + { + case Format::ID::R16G16_UINT: + return RG16UI_to_R16G16_UINT; + default: + break; + } + } + case GL_RG16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16_UNORM: + return RG16_EXT_to_R16G16_UNORM; + default: + break; + } + } + case GL_RG16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16_SNORM: + return RG16_SNORM_EXT_to_R16G16_SNORM; + default: + break; + } + } + case GL_RG32F: + { + switch (angleFormat) + { + case Format::ID::R32G32_FLOAT: + return RG32F_to_R32G32_FLOAT; + default: + break; + } + } + case GL_RG32I: + { + switch (angleFormat) + { + case Format::ID::R32G32_SINT: + return RG32I_to_R32G32_SINT; + default: + break; + } + } + case GL_RG32UI: + { + switch (angleFormat) + { + case Format::ID::R32G32_UINT: + return RG32UI_to_R32G32_UINT; + default: + break; + } + } + case GL_RG8: + { + switch (angleFormat) + { + case Format::ID::R8G8_UNORM: + return RG8_to_R8G8_UNORM; + default: + break; + } + } + case GL_RG8I: + { + switch (angleFormat) + { + case Format::ID::R8G8_SINT: + return RG8I_to_R8G8_SINT; + default: + break; + } + } + case GL_RG8UI: + { + switch (angleFormat) + { + case Format::ID::R8G8_UINT: + return RG8UI_to_R8G8_UINT; + default: + break; + } + } + case GL_RG8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8G8_SNORM: + return RG8_SNORM_to_R8G8_SNORM; + default: + break; + } + } + case GL_RGB: + return RGB_to_default; + case GL_RGB10_A2: + { + switch (angleFormat) + { + case Format::ID::R10G10B10A2_UNORM: + return RGB10_A2_to_R10G10B10A2_UNORM; + default: + break; + } + } + case GL_RGB10_A2UI: + { + switch (angleFormat) + { + case Format::ID::R10G10B10A2_UINT: + return RGB10_A2UI_to_R10G10B10A2_UINT; + default: + break; + } + } + case GL_RGB16F: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return RGB16F_to_R16G16B16A16_FLOAT; + default: + break; + } + } + case GL_RGB16I: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SINT: + return RGB16I_to_R16G16B16A16_SINT; + default: + break; + } + } + case GL_RGB16UI: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UINT: + return RGB16UI_to_R16G16B16A16_UINT; + default: + break; + } + } + case GL_RGB16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UNORM: + return RGB16_EXT_to_R16G16B16A16_UNORM; + default: + break; + } + } + case GL_RGB16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SNORM: + return RGB16_SNORM_EXT_to_R16G16B16A16_SNORM; + default: + break; + } + } + case GL_RGB32F: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_FLOAT: + return RGB32F_to_R32G32B32A32_FLOAT; + default: + break; + } + } + case GL_RGB32I: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_SINT: + return RGB32I_to_R32G32B32A32_SINT; + default: + break; + } + } + case GL_RGB32UI: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_UINT: + return RGB32UI_to_R32G32B32A32_UINT; + default: + break; + } + } + case GL_RGB565: + { + switch (angleFormat) + { + case Format::ID::B5G6R5_UNORM: + return RGB565_to_B5G6R5_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return RGB565_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGB5_A1: + { + switch (angleFormat) + { + case Format::ID::B5G5R5A1_UNORM: + return RGB5_A1_to_B5G5R5A1_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return RGB5_A1_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGB8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return RGB8_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGB8I: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SINT: + return RGB8I_to_R8G8B8A8_SINT; + default: + break; + } + } + case GL_RGB8UI: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UINT: + return RGB8UI_to_R8G8B8A8_UINT; + default: + break; + } + } + case GL_RGB8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SNORM: + return RGB8_SNORM_to_R8G8B8A8_SNORM; + default: + break; + } + } + case GL_RGB9_E5: + { + switch (angleFormat) + { + case Format::ID::R9G9B9E5_SHAREDEXP: + return RGB9_E5_to_R9G9B9E5_SHAREDEXP; + default: + break; + } + } + case GL_RGBA: + return RGBA_to_default; + case GL_RGBA16F: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return RGBA16F_to_R16G16B16A16_FLOAT; + default: + break; + } + } + case GL_RGBA16I: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SINT: + return RGBA16I_to_R16G16B16A16_SINT; + default: + break; + } + } + case GL_RGBA16UI: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UINT: + return RGBA16UI_to_R16G16B16A16_UINT; + default: + break; + } + } + case GL_RGBA16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UNORM: + return RGBA16_EXT_to_R16G16B16A16_UNORM; + default: + break; + } + } + case GL_RGBA16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SNORM: + return RGBA16_SNORM_EXT_to_R16G16B16A16_SNORM; + default: + break; + } + } + case GL_RGBA32F: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_FLOAT: + return RGBA32F_to_R32G32B32A32_FLOAT; + default: + break; + } + } + case GL_RGBA32I: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_SINT: + return RGBA32I_to_R32G32B32A32_SINT; + default: + break; + } + } + case GL_RGBA32UI: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_UINT: + return RGBA32UI_to_R32G32B32A32_UINT; + default: + break; + } + } + case GL_RGBA4: + { + switch (angleFormat) + { + case Format::ID::B4G4R4A4_UNORM: + return RGBA4_to_B4G4R4A4_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return RGBA4_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGBA8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return RGBA8_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGBA8I: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SINT: + return RGBA8I_to_R8G8B8A8_SINT; + default: + break; + } + } + case GL_RGBA8UI: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UINT: + return RGBA8UI_to_R8G8B8A8_UINT; + default: + break; + } + } + case GL_RGBA8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SNORM: + return RGBA8_SNORM_to_R8G8B8A8_SNORM; + default: + break; + } + } + case GL_SRGB8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return SRGB8_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_SRGB8_ALPHA8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return SRGB8_ALPHA8_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_STENCIL_INDEX8: + return STENCIL_INDEX8_to_default; + + default: + { + static LoadFunctionMap emptyLoadFunctionsMap; + return emptyLoadFunctionsMap; + } + } + // clang-format on + +} // GetLoadFunctionsMap + +} // namespace angle diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/BufferNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/BufferNULL.cpp new file mode 100644 index 00000000000..766e78bc6b2 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/BufferNULL.cpp @@ -0,0 +1,74 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BufferNULL.cpp: +// Implements the class methods for BufferNULL. +// + +#include "libANGLE/renderer/null/BufferNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +BufferNULL::BufferNULL() : BufferImpl() +{ +} + +BufferNULL::~BufferNULL() +{ +} + +gl::Error BufferNULL::setData(GLenum target, const void *data, size_t size, GLenum usage) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error BufferNULL::setSubData(GLenum target, const void *data, size_t size, size_t offset) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error BufferNULL::copySubData(BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error BufferNULL::map(GLenum access, GLvoid **mapPtr) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error BufferNULL::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error BufferNULL::unmap(GLboolean *result) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error BufferNULL::getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/BufferNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/BufferNULL.h new file mode 100644 index 00000000000..daa2ce8528c --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/BufferNULL.h @@ -0,0 +1,43 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BufferNULL.h: +// Defines the class interface for BufferNULL, implementing BufferImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_BUFFERNULL_H_ +#define LIBANGLE_RENDERER_NULL_BUFFERNULL_H_ + +#include "libANGLE/renderer/BufferImpl.h" + +namespace rx +{ + +class BufferNULL : public BufferImpl +{ + public: + BufferNULL(); + ~BufferNULL() override; + + gl::Error setData(GLenum target, const void *data, size_t size, GLenum usage) override; + gl::Error setSubData(GLenum target, const void *data, size_t size, size_t offset) override; + gl::Error copySubData(BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + gl::Error map(GLenum access, GLvoid **mapPtr) override; + gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override; + gl::Error unmap(GLboolean *result) override; + + gl::Error getIndexRange(GLenum type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + gl::IndexRange *outRange) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_BUFFERNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/CompilerNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/CompilerNULL.cpp new file mode 100644 index 00000000000..547f4c4e11c --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/CompilerNULL.cpp @@ -0,0 +1,37 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CompilerNULL.cpp: +// Implements the class methods for CompilerNULL. +// + +#include "libANGLE/renderer/null/CompilerNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +CompilerNULL::CompilerNULL() : CompilerImpl() +{ +} + +CompilerNULL::~CompilerNULL() +{ +} + +gl::Error CompilerNULL::release() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +ShShaderOutput CompilerNULL::getTranslatorOutputType() const +{ + UNIMPLEMENTED(); + return ShShaderOutput(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/CompilerNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/CompilerNULL.h new file mode 100644 index 00000000000..5cd85e8bf57 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/CompilerNULL.h @@ -0,0 +1,32 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CompilerNULL.h: +// Defines the class interface for CompilerNULL, implementing CompilerImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_COMPILERNULL_H_ +#define LIBANGLE_RENDERER_NULL_COMPILERNULL_H_ + +#include "libANGLE/renderer/CompilerImpl.h" + +namespace rx +{ + +class CompilerNULL : public CompilerImpl +{ + public: + CompilerNULL(); + ~CompilerNULL() override; + + gl::Error release() override; + + // TODO(jmadill): Expose translator built-in resources init method. + ShShaderOutput getTranslatorOutputType() const override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_COMPILERNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ContextNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/ContextNULL.cpp new file mode 100644 index 00000000000..2f4bcb4f6cc --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ContextNULL.cpp @@ -0,0 +1,175 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextNULL.cpp: +// Implements the class methods for ContextNULL. +// + +#include "libANGLE/renderer/null/ContextNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +ContextNULL::ContextNULL(const gl::ContextState &state) : ContextImpl(state) +{ +} + +ContextNULL::~ContextNULL() +{ +} + +gl::Error ContextNULL::initialize() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error ContextNULL::flush() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error ContextNULL::finish() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error ContextNULL::drawArrays(GLenum mode, GLint first, GLsizei count) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error ContextNULL::drawArraysInstanced(GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error ContextNULL::drawElements(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error ContextNULL::drawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error ContextNULL::drawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +CompilerImpl *ContextNULL::createCompiler() +{ + UNIMPLEMENTED(); + return static_cast<CompilerImpl *>(0); +} + +ShaderImpl *ContextNULL::createShader(const gl::ShaderState &data) +{ + UNIMPLEMENTED(); + return static_cast<ShaderImpl *>(0); +} + +ProgramImpl *ContextNULL::createProgram(const gl::ProgramState &data) +{ + UNIMPLEMENTED(); + return static_cast<ProgramImpl *>(0); +} + +FramebufferImpl *ContextNULL::createFramebuffer(const gl::FramebufferState &data) +{ + UNIMPLEMENTED(); + return static_cast<FramebufferImpl *>(0); +} + +TextureImpl *ContextNULL::createTexture(const gl::TextureState &state) +{ + UNIMPLEMENTED(); + return static_cast<TextureImpl *>(0); +} + +RenderbufferImpl *ContextNULL::createRenderbuffer() +{ + UNIMPLEMENTED(); + return static_cast<RenderbufferImpl *>(0); +} + +BufferImpl *ContextNULL::createBuffer() +{ + UNIMPLEMENTED(); + return static_cast<BufferImpl *>(0); +} + +VertexArrayImpl *ContextNULL::createVertexArray(const gl::VertexArrayState &data) +{ + UNIMPLEMENTED(); + return static_cast<VertexArrayImpl *>(0); +} + +QueryImpl *ContextNULL::createQuery(GLenum type) +{ + UNIMPLEMENTED(); + return static_cast<QueryImpl *>(0); +} + +FenceNVImpl *ContextNULL::createFenceNV() +{ + UNIMPLEMENTED(); + return static_cast<FenceNVImpl *>(0); +} + +FenceSyncImpl *ContextNULL::createFenceSync() +{ + UNIMPLEMENTED(); + return static_cast<FenceSyncImpl *>(0); +} + +TransformFeedbackImpl *ContextNULL::createTransformFeedback(const gl::TransformFeedbackState &state) +{ + UNIMPLEMENTED(); + return static_cast<TransformFeedbackImpl *>(0); +} + +SamplerImpl *ContextNULL::createSampler() +{ + UNIMPLEMENTED(); + return static_cast<SamplerImpl *>(0); +} + +std::vector<PathImpl *> ContextNULL::createPaths(GLsizei range) +{ + UNIMPLEMENTED(); + return std::vector<PathImpl *>(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ContextNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/ContextNULL.h new file mode 100644 index 00000000000..3fc40b62e9d --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ContextNULL.h @@ -0,0 +1,95 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextNULL.h: +// Defines the class interface for ContextNULL, implementing ContextImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_CONTEXTNULL_H_ +#define LIBANGLE_RENDERER_NULL_CONTEXTNULL_H_ + +#include "libANGLE/renderer/ContextImpl.h" + +namespace rx +{ + +class ContextNULL : public ContextImpl +{ + public: + ContextNULL(const gl::ContextState &state); + ~ContextNULL() override; + + gl::Error initialize() override; + + // Flush and finish. + gl::Error flush() override; + gl::Error finish() override; + + // Drawing methods. + gl::Error drawArrays(GLenum mode, GLint first, GLsizei count) override; + gl::Error drawArraysInstanced(GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; + + gl::Error drawElements(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) override; + gl::Error drawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instances, + const gl::IndexRange &indexRange) override; + gl::Error drawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices, + const gl::IndexRange &indexRange) override; + + // CHROMIUM_path_rendering path drawing methods. + + // Shader creation + CompilerImpl *createCompiler() override; + ShaderImpl *createShader(const gl::ShaderState &data) override; + ProgramImpl *createProgram(const gl::ProgramState &data) override; + + // Framebuffer creation + FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; + + // Texture creation + TextureImpl *createTexture(const gl::TextureState &state) override; + + // Renderbuffer creation + RenderbufferImpl *createRenderbuffer() override; + + // Buffer creation + BufferImpl *createBuffer() override; + + // Vertex Array creation + VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override; + + // Query and Fence creation + QueryImpl *createQuery(GLenum type) override; + FenceNVImpl *createFenceNV() override; + FenceSyncImpl *createFenceSync() override; + + // Transform Feedback creation + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; + + // Sampler object creation + SamplerImpl *createSampler() override; + + std::vector<PathImpl *> createPaths(GLsizei range) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_CONTEXTNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/DeviceNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/DeviceNULL.cpp new file mode 100644 index 00000000000..4893f946623 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/DeviceNULL.cpp @@ -0,0 +1,48 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DeviceNULL.cpp: +// Implements the class methods for DeviceNULL. +// + +#include "libANGLE/renderer/null/DeviceNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +DeviceNULL::DeviceNULL() : DeviceImpl() +{ +} + +DeviceNULL::~DeviceNULL() +{ +} + +egl::Error DeviceNULL::getDevice(void **outValue) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +EGLint DeviceNULL::getType() +{ + UNIMPLEMENTED(); + return EGLint(); +} + +void DeviceNULL::generateExtensions(egl::DeviceExtensions *outExtensions) const +{ + UNIMPLEMENTED(); +} + +bool DeviceNULL::deviceExternallySourced() +{ + UNIMPLEMENTED(); + return bool(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/DeviceNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/DeviceNULL.h new file mode 100644 index 00000000000..ed921039e7a --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/DeviceNULL.h @@ -0,0 +1,32 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DeviceNULL.h: +// Defines the class interface for DeviceNULL, implementing DeviceImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_DEVICENULL_H_ +#define LIBANGLE_RENDERER_NULL_DEVICENULL_H_ + +#include "libANGLE/renderer/DeviceImpl.h" + +namespace rx +{ + +class DeviceNULL : public DeviceImpl +{ + public: + DeviceNULL(); + ~DeviceNULL() override; + + egl::Error getDevice(void **outValue) override; + EGLint getType() override; + void generateExtensions(egl::DeviceExtensions *outExtensions) const override; + bool deviceExternallySourced() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_DEVICENULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/DisplayNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/DisplayNULL.cpp new file mode 100644 index 00000000000..bdf6d4a1450 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/DisplayNULL.cpp @@ -0,0 +1,167 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DisplayNULL.cpp: +// Implements the class methods for DisplayNULL. +// + +#include "libANGLE/renderer/null/DisplayNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +DisplayNULL::DisplayNULL() : DisplayImpl() +{ +} + +DisplayNULL::~DisplayNULL() +{ +} + +egl::Error DisplayNULL::initialize(egl::Display *display) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +void DisplayNULL::terminate() +{ + UNIMPLEMENTED(); +} + +egl::Error DisplayNULL::makeCurrent(egl::Surface *drawSurface, + egl::Surface *readSurface, + gl::Context *context) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +egl::ConfigSet DisplayNULL::generateConfigs() +{ + UNIMPLEMENTED(); + return egl::ConfigSet(); +} + +bool DisplayNULL::testDeviceLost() +{ + UNIMPLEMENTED(); + return bool(); +} + +egl::Error DisplayNULL::restoreLostDevice() +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +bool DisplayNULL::isValidNativeWindow(EGLNativeWindowType window) const +{ + UNIMPLEMENTED(); + return bool(); +} + +std::string DisplayNULL::getVendorString() const +{ + UNIMPLEMENTED(); + return std::string(); +} + +egl::Error DisplayNULL::getDevice(DeviceImpl **device) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +egl::Error DisplayNULL::waitClient() const +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +egl::Error DisplayNULL::waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +gl::Version DisplayNULL::getMaxSupportedESVersion() const +{ + UNIMPLEMENTED(); + return gl::Version(); +} + +SurfaceImpl *DisplayNULL::createWindowSurface(const egl::SurfaceState &state, + const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return static_cast<SurfaceImpl *>(0); +} + +SurfaceImpl *DisplayNULL::createPbufferSurface(const egl::SurfaceState &state, + const egl::Config *configuration, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return static_cast<SurfaceImpl *>(0); +} + +SurfaceImpl *DisplayNULL::createPbufferFromClientBuffer(const egl::SurfaceState &state, + const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return static_cast<SurfaceImpl *>(0); +} + +SurfaceImpl *DisplayNULL::createPixmapSurface(const egl::SurfaceState &state, + const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return static_cast<SurfaceImpl *>(0); +} + +ImageImpl *DisplayNULL::createImage(EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return static_cast<ImageImpl *>(0); +} + +ContextImpl *DisplayNULL::createContext(const gl::ContextState &state) +{ + UNIMPLEMENTED(); + return static_cast<ContextImpl *>(0); +} + +StreamProducerImpl *DisplayNULL::createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) +{ + UNIMPLEMENTED(); + return static_cast<StreamProducerImpl *>(0); +} + +void DisplayNULL::generateExtensions(egl::DisplayExtensions *outExtensions) const +{ + UNIMPLEMENTED(); +} + +void DisplayNULL::generateCaps(egl::Caps *outCaps) const +{ + UNIMPLEMENTED(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/DisplayNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/DisplayNULL.h new file mode 100644 index 00000000000..8a750b1d206 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/DisplayNULL.h @@ -0,0 +1,81 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DisplayNULL.h: +// Defines the class interface for DisplayNULL, implementing DisplayImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_DISPLAYNULL_H_ +#define LIBANGLE_RENDERER_NULL_DISPLAYNULL_H_ + +#include "libANGLE/renderer/DisplayImpl.h" + +namespace rx +{ + +class DisplayNULL : public DisplayImpl +{ + public: + DisplayNULL(); + ~DisplayNULL() override; + + egl::Error initialize(egl::Display *display) override; + void terminate() override; + + egl::Error makeCurrent(egl::Surface *drawSurface, + egl::Surface *readSurface, + gl::Context *context) override; + + egl::ConfigSet generateConfigs() override; + + bool testDeviceLost() override; + egl::Error restoreLostDevice() override; + + bool isValidNativeWindow(EGLNativeWindowType window) const override; + + std::string getVendorString() const override; + + egl::Error getDevice(DeviceImpl **device) override; + + egl::Error waitClient() const override; + egl::Error waitNative(EGLint engine, + egl::Surface *drawSurface, + egl::Surface *readSurface) const override; + gl::Version getMaxSupportedESVersion() const override; + + SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, + const egl::Config *configuration, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, + const egl::Config *configuration, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, + const egl::Config *configuration, + EGLClientBuffer shareHandle, + const egl::AttributeMap &attribs) override; + SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, + const egl::Config *configuration, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) override; + + ImageImpl *createImage(EGLenum target, + egl::ImageSibling *buffer, + const egl::AttributeMap &attribs) override; + + ContextImpl *createContext(const gl::ContextState &state) override; + + StreamProducerImpl *createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; + + private: + void generateExtensions(egl::DisplayExtensions *outExtensions) const override; + void generateCaps(egl::Caps *outCaps) const override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_DISPLAYNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/FenceNVNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceNVNULL.cpp new file mode 100644 index 00000000000..9d7f26043e2 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceNVNULL.cpp @@ -0,0 +1,43 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FenceNVNULL.cpp: +// Implements the class methods for FenceNVNULL. +// + +#include "libANGLE/renderer/null/FenceNVNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +FenceNVNULL::FenceNVNULL() : FenceNVImpl() +{ +} + +FenceNVNULL::~FenceNVNULL() +{ +} + +gl::Error FenceNVNULL::set(GLenum condition) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FenceNVNULL::test(GLboolean *outFinished) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FenceNVNULL::finish() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/FenceNVNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceNVNULL.h new file mode 100644 index 00000000000..10cf5c2cbdd --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceNVNULL.h @@ -0,0 +1,31 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FenceNVNULL.h: +// Defines the class interface for FenceNVNULL, implementing FenceNVImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_FENCENVNULL_H_ +#define LIBANGLE_RENDERER_NULL_FENCENVNULL_H_ + +#include "libANGLE/renderer/FenceNVImpl.h" + +namespace rx +{ + +class FenceNVNULL : public FenceNVImpl +{ + public: + FenceNVNULL(); + ~FenceNVNULL() override; + + gl::Error set(GLenum condition) override; + gl::Error test(GLboolean *outFinished) override; + gl::Error finish() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_FENCENVNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/FenceSyncNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceSyncNULL.cpp new file mode 100644 index 00000000000..37bfdfedb61 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceSyncNULL.cpp @@ -0,0 +1,49 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FenceSyncNULL.cpp: +// Implements the class methods for FenceSyncNULL. +// + +#include "libANGLE/renderer/null/FenceSyncNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +FenceSyncNULL::FenceSyncNULL() : FenceSyncImpl() +{ +} + +FenceSyncNULL::~FenceSyncNULL() +{ +} + +gl::Error FenceSyncNULL::set(GLenum condition, GLbitfield flags) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FenceSyncNULL::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FenceSyncNULL::serverWait(GLbitfield flags, GLuint64 timeout) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FenceSyncNULL::getStatus(GLint *outResult) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/FenceSyncNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceSyncNULL.h new file mode 100644 index 00000000000..28a12f703cd --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/FenceSyncNULL.h @@ -0,0 +1,32 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FenceSyncNULL.h: +// Defines the class interface for FenceSyncNULL, implementing FenceSyncImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_FENCESYNCNULL_H_ +#define LIBANGLE_RENDERER_NULL_FENCESYNCNULL_H_ + +#include "libANGLE/renderer/FenceSyncImpl.h" + +namespace rx +{ + +class FenceSyncNULL : public FenceSyncImpl +{ + public: + FenceSyncNULL(); + ~FenceSyncNULL() override; + + gl::Error set(GLenum condition, GLbitfield flags) override; + gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) override; + gl::Error serverWait(GLbitfield flags, GLuint64 timeout) override; + gl::Error getStatus(GLint *outResult) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_FENCESYNCNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/FramebufferNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/FramebufferNULL.cpp new file mode 100644 index 00000000000..14ebe1eba7f --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/FramebufferNULL.cpp @@ -0,0 +1,131 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FramebufferNULL.cpp: +// Implements the class methods for FramebufferNULL. +// + +#include "libANGLE/renderer/null/FramebufferNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +FramebufferNULL::FramebufferNULL(const gl::FramebufferState &state) : FramebufferImpl(state) +{ +} + +FramebufferNULL::~FramebufferNULL() +{ +} + +gl::Error FramebufferNULL::discard(size_t count, const GLenum *attachments) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::invalidate(size_t count, const GLenum *attachments) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::invalidateSub(size_t count, + const GLenum *attachments, + const gl::Rectangle &area) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::clear(ContextImpl *context, GLbitfield mask) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::clearBufferfv(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::clearBufferuiv(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::clearBufferiv(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::clearBufferfi(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +GLenum FramebufferNULL::getImplementationColorReadFormat() const +{ + UNIMPLEMENTED(); + return GLenum(); +} + +GLenum FramebufferNULL::getImplementationColorReadType() const +{ + UNIMPLEMENTED(); + return GLenum(); +} + +gl::Error FramebufferNULL::readPixels(ContextImpl *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + GLvoid *pixels) const +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error FramebufferNULL::blit(ContextImpl *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +bool FramebufferNULL::checkStatus() const +{ + UNIMPLEMENTED(); + return bool(); +} + +void FramebufferNULL::syncState(const gl::Framebuffer::DirtyBits &dirtyBits) +{ + UNIMPLEMENTED(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/FramebufferNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/FramebufferNULL.h new file mode 100644 index 00000000000..c53132c18d1 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/FramebufferNULL.h @@ -0,0 +1,70 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FramebufferNULL.h: +// Defines the class interface for FramebufferNULL, implementing FramebufferImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_FRAMEBUFFERNULL_H_ +#define LIBANGLE_RENDERER_NULL_FRAMEBUFFERNULL_H_ + +#include "libANGLE/renderer/FramebufferImpl.h" + +namespace rx +{ + +class FramebufferNULL : public FramebufferImpl +{ + public: + FramebufferNULL(const gl::FramebufferState &state); + ~FramebufferNULL() override; + + gl::Error discard(size_t count, const GLenum *attachments) override; + gl::Error invalidate(size_t count, const GLenum *attachments) override; + gl::Error invalidateSub(size_t count, + const GLenum *attachments, + const gl::Rectangle &area) override; + + gl::Error clear(ContextImpl *context, GLbitfield mask) override; + gl::Error clearBufferfv(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + const GLfloat *values) override; + gl::Error clearBufferuiv(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + const GLuint *values) override; + gl::Error clearBufferiv(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values) override; + gl::Error clearBufferfi(ContextImpl *context, + GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil) override; + + GLenum getImplementationColorReadFormat() const override; + GLenum getImplementationColorReadType() const override; + gl::Error readPixels(ContextImpl *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + GLvoid *pixels) const override; + + gl::Error blit(ContextImpl *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) override; + + bool checkStatus() const override; + + void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_FRAMEBUFFERNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ImageNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/ImageNULL.cpp new file mode 100644 index 00000000000..23f3ca09949 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ImageNULL.cpp @@ -0,0 +1,37 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ImageNULL.cpp: +// Implements the class methods for ImageNULL. +// + +#include "libANGLE/renderer/null/ImageNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +ImageNULL::ImageNULL() : ImageImpl() +{ +} + +ImageNULL::~ImageNULL() +{ +} + +egl::Error ImageNULL::initialize() +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +gl::Error ImageNULL::orphan(egl::ImageSibling *sibling) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ImageNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/ImageNULL.h new file mode 100644 index 00000000000..b88b346ddfa --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ImageNULL.h @@ -0,0 +1,30 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ImageNULL.h: +// Defines the class interface for ImageNULL, implementing ImageImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_IMAGENULL_H_ +#define LIBANGLE_RENDERER_NULL_IMAGENULL_H_ + +#include "libANGLE/renderer/ImageImpl.h" + +namespace rx +{ + +class ImageNULL : public ImageImpl +{ + public: + ImageNULL(); + ~ImageNULL() override; + egl::Error initialize() override; + + gl::Error orphan(egl::ImageSibling *sibling) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_IMAGENULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/PathNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/PathNULL.cpp new file mode 100644 index 00000000000..bb52ea2c29d --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/PathNULL.cpp @@ -0,0 +1,40 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PathNULL.cpp: +// Implements the class methods for PathNULL. +// + +#include "libANGLE/renderer/null/PathNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +PathNULL::PathNULL() : PathImpl() +{ +} + +PathNULL::~PathNULL() +{ +} + +gl::Error PathNULL::setCommands(GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +void PathNULL::setPathParameter(GLenum pname, GLfloat value) +{ + UNIMPLEMENTED(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/PathNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/PathNULL.h new file mode 100644 index 00000000000..4c80c1c9135 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/PathNULL.h @@ -0,0 +1,35 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PathNULL.h: +// Defines the class interface for PathNULL, implementing PathImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_PATHNULL_H_ +#define LIBANGLE_RENDERER_NULL_PATHNULL_H_ + +#include "libANGLE/renderer/PathImpl.h" + +namespace rx +{ + +class PathNULL : public PathImpl +{ + public: + PathNULL(); + ~PathNULL() override; + + gl::Error setCommands(GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) override; + + void setPathParameter(GLenum pname, GLfloat value) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_PATHNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ProgramNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/ProgramNULL.cpp new file mode 100644 index 00000000000..28cab4d367d --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ProgramNULL.cpp @@ -0,0 +1,212 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramNULL.cpp: +// Implements the class methods for ProgramNULL. +// + +#include "libANGLE/renderer/null/ProgramNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +ProgramNULL::ProgramNULL(const gl::ProgramState &state) : ProgramImpl(state) +{ +} + +ProgramNULL::~ProgramNULL() +{ +} + +LinkResult ProgramNULL::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) +{ + UNIMPLEMENTED(); + return LinkResult(false, gl::Error(GL_INVALID_OPERATION)); +} + +gl::Error ProgramNULL::save(gl::BinaryOutputStream *stream) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +void ProgramNULL::setBinaryRetrievableHint(bool retrievable) +{ + UNIMPLEMENTED(); +} + +LinkResult ProgramNULL::link(const gl::ContextState &data, gl::InfoLog &infoLog) +{ + UNIMPLEMENTED(); + return LinkResult(false, gl::Error(GL_INVALID_OPERATION)); +} + +GLboolean ProgramNULL::validate(const gl::Caps &caps, gl::InfoLog *infoLog) +{ + UNIMPLEMENTED(); + return GLboolean(); +} + +void ProgramNULL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform1iv(GLint location, GLsizei count, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform2iv(GLint location, GLsizei count, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform3iv(GLint location, GLsizei count, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform4iv(GLint location, GLsizei count, const GLint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + UNIMPLEMENTED(); +} + +void ProgramNULL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) +{ + UNIMPLEMENTED(); +} + +bool ProgramNULL::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const +{ + UNIMPLEMENTED(); + return bool(); +} + +bool ProgramNULL::getUniformBlockMemberInfo(const std::string &memberUniformName, + sh::BlockMemberInfo *memberInfoOut) const +{ + UNIMPLEMENTED(); + return bool(); +} + +void ProgramNULL::setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + UNIMPLEMENTED(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ProgramNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/ProgramNULL.h new file mode 100644 index 00000000000..576a52c1835 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ProgramNULL.h @@ -0,0 +1,101 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramNULL.h: +// Defines the class interface for ProgramNULL, implementing ProgramImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_PROGRAMNULL_H_ +#define LIBANGLE_RENDERER_NULL_PROGRAMNULL_H_ + +#include "libANGLE/renderer/ProgramImpl.h" + +namespace rx +{ + +class ProgramNULL : public ProgramImpl +{ + public: + ProgramNULL(const gl::ProgramState &state); + ~ProgramNULL() override; + + LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override; + gl::Error save(gl::BinaryOutputStream *stream) override; + void setBinaryRetrievableHint(bool retrievable) override; + + LinkResult link(const gl::ContextState &data, gl::InfoLog &infoLog) override; + GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; + + void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform1iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform2iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform3iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform4iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + void setUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) override; + + // TODO: synchronize in syncState when dirty bits exist. + void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; + + // May only be called after a successful link operation. + // Return false for inactive blocks. + bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override; + + // May only be called after a successful link operation. + // Returns false for inactive members. + bool getUniformBlockMemberInfo(const std::string &memberUniformName, + sh::BlockMemberInfo *memberInfoOut) const override; + // CHROMIUM_path_rendering + // Set parameters to control fragment shader input variable interpolation + void setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_PROGRAMNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/QueryNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/QueryNULL.cpp new file mode 100644 index 00000000000..6276a0ff165 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/QueryNULL.cpp @@ -0,0 +1,73 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// QueryNULL.cpp: +// Implements the class methods for QueryNULL. +// + +#include "libANGLE/renderer/null/QueryNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +QueryNULL::QueryNULL(GLenum type) : QueryImpl(type) +{ +} + +QueryNULL::~QueryNULL() +{ +} + +gl::Error QueryNULL::begin() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error QueryNULL::end() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error QueryNULL::queryCounter() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error QueryNULL::getResult(GLint *params) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error QueryNULL::getResult(GLuint *params) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error QueryNULL::getResult(GLint64 *params) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error QueryNULL::getResult(GLuint64 *params) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error QueryNULL::isResultAvailable(bool *available) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/QueryNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/QueryNULL.h new file mode 100644 index 00000000000..40082a9b858 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/QueryNULL.h @@ -0,0 +1,36 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// QueryNULL.h: +// Defines the class interface for QueryNULL, implementing QueryImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_QUERYNULL_H_ +#define LIBANGLE_RENDERER_NULL_QUERYNULL_H_ + +#include "libANGLE/renderer/QueryImpl.h" + +namespace rx +{ + +class QueryNULL : public QueryImpl +{ + public: + QueryNULL(GLenum type); + ~QueryNULL() override; + + gl::Error begin() override; + gl::Error end() override; + gl::Error queryCounter() override; + gl::Error getResult(GLint *params) override; + gl::Error getResult(GLuint *params) override; + gl::Error getResult(GLint64 *params) override; + gl::Error getResult(GLuint64 *params) override; + gl::Error isResultAvailable(bool *available) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_QUERYNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/RenderbufferNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/RenderbufferNULL.cpp new file mode 100644 index 00000000000..50f54a62037 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/RenderbufferNULL.cpp @@ -0,0 +1,46 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RenderbufferNULL.cpp: +// Implements the class methods for RenderbufferNULL. +// + +#include "libANGLE/renderer/null/RenderbufferNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +RenderbufferNULL::RenderbufferNULL() : RenderbufferImpl() +{ +} + +RenderbufferNULL::~RenderbufferNULL() +{ +} + +gl::Error RenderbufferNULL::setStorage(GLenum internalformat, size_t width, size_t height) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error RenderbufferNULL::setStorageMultisample(size_t samples, + GLenum internalformat, + size_t width, + size_t height) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error RenderbufferNULL::setStorageEGLImageTarget(egl::Image *image) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/RenderbufferNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/RenderbufferNULL.h new file mode 100644 index 00000000000..79e529c4ca9 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/RenderbufferNULL.h @@ -0,0 +1,34 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RenderbufferNULL.h: +// Defines the class interface for RenderbufferNULL, implementing RenderbufferImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_RENDERBUFFERNULL_H_ +#define LIBANGLE_RENDERER_NULL_RENDERBUFFERNULL_H_ + +#include "libANGLE/renderer/RenderbufferImpl.h" + +namespace rx +{ + +class RenderbufferNULL : public RenderbufferImpl +{ + public: + RenderbufferNULL(); + ~RenderbufferNULL() override; + + gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override; + gl::Error setStorageMultisample(size_t samples, + GLenum internalformat, + size_t width, + size_t height) override; + gl::Error setStorageEGLImageTarget(egl::Image *image) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_RENDERBUFFERNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/SamplerNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/SamplerNULL.cpp new file mode 100644 index 00000000000..e1e8c7c62f5 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/SamplerNULL.cpp @@ -0,0 +1,25 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SamplerNULL.cpp: +// Implements the class methods for SamplerNULL. +// + +#include "libANGLE/renderer/null/SamplerNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +SamplerNULL::SamplerNULL() : SamplerImpl() +{ +} + +SamplerNULL::~SamplerNULL() +{ +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/SamplerNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/SamplerNULL.h new file mode 100644 index 00000000000..031fafa3940 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/SamplerNULL.h @@ -0,0 +1,27 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SamplerNULL.h: +// Defines the class interface for SamplerNULL, implementing SamplerImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_SAMPLERNULL_H_ +#define LIBANGLE_RENDERER_NULL_SAMPLERNULL_H_ + +#include "libANGLE/renderer/SamplerImpl.h" + +namespace rx +{ + +class SamplerNULL : public SamplerImpl +{ + public: + SamplerNULL(); + ~SamplerNULL() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_SAMPLERNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ShaderNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/ShaderNULL.cpp new file mode 100644 index 00000000000..168f4bdcaa6 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ShaderNULL.cpp @@ -0,0 +1,44 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ShaderNULL.cpp: +// Implements the class methods for ShaderNULL. +// + +#include "libANGLE/renderer/null/ShaderNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +ShaderNULL::ShaderNULL(const gl::ShaderState &data) : ShaderImpl(data) +{ +} + +ShaderNULL::~ShaderNULL() +{ +} + +ShCompileOptions ShaderNULL::prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) +{ + UNIMPLEMENTED(); + return ShCompileOptions(); +} + +bool ShaderNULL::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) +{ + UNIMPLEMENTED(); + return bool(); +} + +std::string ShaderNULL::getDebugInfo() const +{ + UNIMPLEMENTED(); + return std::string(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/ShaderNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/ShaderNULL.h new file mode 100644 index 00000000000..f7d89710bf3 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/ShaderNULL.h @@ -0,0 +1,35 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ShaderNULL.h: +// Defines the class interface for ShaderNULL, implementing ShaderImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_SHADERNULL_H_ +#define LIBANGLE_RENDERER_NULL_SHADERNULL_H_ + +#include "libANGLE/renderer/ShaderImpl.h" + +namespace rx +{ + +class ShaderNULL : public ShaderImpl +{ + public: + ShaderNULL(const gl::ShaderState &data); + ~ShaderNULL() override; + + // Returns additional ShCompile options. + ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) override; + // Returns success for compiling on the driver. Returns success. + bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override; + + std::string getDebugInfo() const override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_SHADERNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/SurfaceNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/SurfaceNULL.cpp new file mode 100644 index 00000000000..81d76378318 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/SurfaceNULL.cpp @@ -0,0 +1,103 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SurfaceNULL.cpp: +// Implements the class methods for SurfaceNULL. +// + +#include "libANGLE/renderer/null/SurfaceNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +SurfaceNULL::SurfaceNULL(const egl::SurfaceState &surfaceState) : SurfaceImpl(surfaceState) +{ +} + +SurfaceNULL::~SurfaceNULL() +{ +} + +egl::Error SurfaceNULL::initialize() +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +FramebufferImpl *SurfaceNULL::createDefaultFramebuffer(const gl::FramebufferState &state) +{ + UNIMPLEMENTED(); + return static_cast<FramebufferImpl *>(0); +} + +egl::Error SurfaceNULL::swap() +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +egl::Error SurfaceNULL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +egl::Error SurfaceNULL::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +egl::Error SurfaceNULL::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +egl::Error SurfaceNULL::releaseTexImage(EGLint buffer) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_BAD_ACCESS); +} + +void SurfaceNULL::setSwapInterval(EGLint interval) +{ + UNIMPLEMENTED(); +} + +EGLint SurfaceNULL::getWidth() const +{ + UNIMPLEMENTED(); + return EGLint(); +} + +EGLint SurfaceNULL::getHeight() const +{ + UNIMPLEMENTED(); + return EGLint(); +} + +EGLint SurfaceNULL::isPostSubBufferSupported() const +{ + UNIMPLEMENTED(); + return EGLint(); +} + +EGLint SurfaceNULL::getSwapBehavior() const +{ + UNIMPLEMENTED(); + return EGLint(); +} + +gl::Error SurfaceNULL::getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, + FramebufferAttachmentRenderTarget **rtOut) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/SurfaceNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/SurfaceNULL.h new file mode 100644 index 00000000000..597f1c21c94 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/SurfaceNULL.h @@ -0,0 +1,46 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SurfaceNULL.h: +// Defines the class interface for SurfaceNULL, implementing SurfaceImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_SURFACENULL_H_ +#define LIBANGLE_RENDERER_NULL_SURFACENULL_H_ + +#include "libANGLE/renderer/SurfaceImpl.h" + +namespace rx +{ + +class SurfaceNULL : public SurfaceImpl +{ + public: + SurfaceNULL(const egl::SurfaceState &surfaceState); + ~SurfaceNULL() override; + + egl::Error initialize() override; + FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; + egl::Error swap() override; + egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; + egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; + egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; + egl::Error releaseTexImage(EGLint buffer) override; + void setSwapInterval(EGLint interval) override; + + // width and height can change with client window resizing + EGLint getWidth() const override; + EGLint getHeight() const override; + + EGLint isPostSubBufferSupported() const override; + EGLint getSwapBehavior() const override; + + gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, + FramebufferAttachmentRenderTarget **rtOut) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_SURFACENULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.cpp new file mode 100644 index 00000000000..2f9a57c9fa5 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.cpp @@ -0,0 +1,138 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureNULL.cpp: +// Implements the class methods for TextureNULL. +// + +#include "libANGLE/renderer/null/TextureNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +TextureNULL::TextureNULL(const gl::TextureState &state) : TextureImpl(state) +{ +} + +TextureNULL::~TextureNULL() +{ +} + +gl::Error TextureNULL::setImage(GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::setSubImage(GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::setCompressedImage(GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::setCompressedSubImage(GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::copyImage(GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::copySubImage(GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::setStorage(GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::setEGLImageTarget(GLenum target, egl::Image *image) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::setImageExternal(GLenum target, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +gl::Error TextureNULL::generateMipmap() +{ + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION); +} + +void TextureNULL::setBaseLevel(GLuint baseLevel) +{ + UNIMPLEMENTED(); +} + +void TextureNULL::bindTexImage(egl::Surface *surface) +{ + UNIMPLEMENTED(); +} + +void TextureNULL::releaseTexImage() +{ + UNIMPLEMENTED(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.h new file mode 100644 index 00000000000..23a332c5768 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/TextureNULL.h @@ -0,0 +1,87 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureNULL.h: +// Defines the class interface for TextureNULL, implementing TextureImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_TEXTURENULL_H_ +#define LIBANGLE_RENDERER_NULL_TEXTURENULL_H_ + +#include "libANGLE/renderer/TextureImpl.h" + +namespace rx +{ + +class TextureNULL : public TextureImpl +{ + public: + TextureNULL(const gl::TextureState &state); + ~TextureNULL() override; + + gl::Error setImage(GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + gl::Error setSubImage(GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + + gl::Error setCompressedImage(GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + gl::Error setCompressedSubImage(GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + gl::Error copyImage(GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source) override; + gl::Error copySubImage(GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; + + gl::Error setStorage(GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + + gl::Error setImageExternal(GLenum target, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + + gl::Error generateMipmap() override; + + void setBaseLevel(GLuint baseLevel) override; + + void bindTexImage(egl::Surface *surface) override; + void releaseTexImage() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_TEXTURENULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/TransformFeedbackNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/TransformFeedbackNULL.cpp new file mode 100644 index 00000000000..e1433fb2d05 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/TransformFeedbackNULL.cpp @@ -0,0 +1,57 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TransformFeedbackNULL.cpp: +// Implements the class methods for TransformFeedbackNULL. +// + +#include "libANGLE/renderer/null/TransformFeedbackNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +TransformFeedbackNULL::TransformFeedbackNULL(const gl::TransformFeedbackState &state) + : TransformFeedbackImpl(state) +{ +} + +TransformFeedbackNULL::~TransformFeedbackNULL() +{ +} + +void TransformFeedbackNULL::begin(GLenum primitiveMode) +{ + UNIMPLEMENTED(); +} + +void TransformFeedbackNULL::end() +{ + UNIMPLEMENTED(); +} + +void TransformFeedbackNULL::pause() +{ + UNIMPLEMENTED(); +} + +void TransformFeedbackNULL::resume() +{ + UNIMPLEMENTED(); +} + +void TransformFeedbackNULL::bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) +{ + UNIMPLEMENTED(); +} + +void TransformFeedbackNULL::bindIndexedBuffer(size_t index, + const OffsetBindingPointer<gl::Buffer> &binding) +{ + UNIMPLEMENTED(); +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/TransformFeedbackNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/TransformFeedbackNULL.h new file mode 100644 index 00000000000..477e81d85a6 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/TransformFeedbackNULL.h @@ -0,0 +1,35 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TransformFeedbackNULL.h: +// Defines the class interface for TransformFeedbackNULL, implementing TransformFeedbackImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_TRANSFORMFEEDBACKNULL_H_ +#define LIBANGLE_RENDERER_NULL_TRANSFORMFEEDBACKNULL_H_ + +#include "libANGLE/renderer/TransformFeedbackImpl.h" + +namespace rx +{ + +class TransformFeedbackNULL : public TransformFeedbackImpl +{ + public: + TransformFeedbackNULL(const gl::TransformFeedbackState &state); + ~TransformFeedbackNULL() override; + + void begin(GLenum primitiveMode) override; + void end() override; + void pause() override; + void resume() override; + + void bindGenericBuffer(const BindingPointer<gl::Buffer> &binding) override; + void bindIndexedBuffer(size_t index, const OffsetBindingPointer<gl::Buffer> &binding) override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_TRANSFORMFEEDBACKNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/VertexArrayNULL.cpp b/chromium/third_party/angle/src/libANGLE/renderer/null/VertexArrayNULL.cpp new file mode 100644 index 00000000000..95a835df160 --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/VertexArrayNULL.cpp @@ -0,0 +1,25 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VertexArrayNULL.cpp: +// Implements the class methods for VertexArrayNULL. +// + +#include "libANGLE/renderer/null/VertexArrayNULL.h" + +#include "common/debug.h" + +namespace rx +{ + +VertexArrayNULL::VertexArrayNULL(const gl::VertexArrayState &data) : VertexArrayImpl(data) +{ +} + +VertexArrayNULL::~VertexArrayNULL() +{ +} + +} // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/null/VertexArrayNULL.h b/chromium/third_party/angle/src/libANGLE/renderer/null/VertexArrayNULL.h new file mode 100644 index 00000000000..f8b2b0490ca --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/renderer/null/VertexArrayNULL.h @@ -0,0 +1,27 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VertexArrayNULL.h: +// Defines the class interface for VertexArrayNULL, implementing VertexArrayImpl. +// + +#ifndef LIBANGLE_RENDERER_NULL_VERTEXARRAYNULL_H_ +#define LIBANGLE_RENDERER_NULL_VERTEXARRAYNULL_H_ + +#include "libANGLE/renderer/VertexArrayImpl.h" + +namespace rx +{ + +class VertexArrayNULL : public VertexArrayImpl +{ + public: + VertexArrayNULL(const gl::VertexArrayState &data); + ~VertexArrayNULL() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_NULL_VERTEXARRAYNULL_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp b/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp index ea6fee72c4b..b93a1ff93f5 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.cpp @@ -9,9 +9,13 @@ #include "libANGLE/renderer/renderer_utils.h" +#include "image_util/copyimage.h" +#include "image_util/imageformats.h" + #include "libANGLE/formatutils.h" -#include "libANGLE/renderer/copyimage.h" -#include "libANGLE/renderer/imageformats.h" +#include "libANGLE/renderer/Format.h" + +#include <string.h> namespace rx { @@ -31,6 +35,8 @@ static inline void InsertFormatWriteFunctionMapping(FormatWriteFunctionMap *map, static FormatWriteFunctionMap BuildFormatWriteFunctionMap() { + using namespace angle; // For image writing functions + FormatWriteFunctionMap map; // clang-format off @@ -165,9 +171,7 @@ PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, } void PackPixels(const PackPixelsParams ¶ms, - const gl::InternalFormat &sourceFormatInfo, - const FastCopyFunctionMap &fastCopyFunctionsMap, - ColorReadFunction colorReadFunction, + const angle::Format &sourceFormat, int inputPitchIn, const uint8_t *sourceIn, uint8_t *destWithoutOffset) @@ -183,19 +187,24 @@ void PackPixels(const PackPixelsParams ¶ms, inputPitch = -inputPitch; } - if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type) + const auto &sourceGLInfo = gl::GetInternalFormatInfo(sourceFormat.glInternalFormat); + + if (sourceGLInfo.format == params.format && sourceGLInfo.type == params.type) { // Direct copy possible for (int y = 0; y < params.area.height; ++y) { memcpy(destWithOffset + y * params.outputPitch, source + y * inputPitch, - params.area.width * sourceFormatInfo.pixelBytes); + params.area.width * sourceGLInfo.pixelBytes); } return; } + ASSERT(sourceGLInfo.pixelBytes > 0); + gl::FormatType formatType(params.format, params.type); - ColorCopyFunction fastCopyFunc = GetFastCopyFunction(fastCopyFunctionsMap, formatType); + ColorCopyFunction fastCopyFunc = + GetFastCopyFunction(sourceFormat.fastCopyFunctions, formatType); GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(formatType.format, formatType.type); const auto &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat); @@ -208,7 +217,7 @@ void PackPixels(const PackPixelsParams ¶ms, { uint8_t *dest = destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceGLInfo.pixelBytes; fastCopyFunc(src, dest); } @@ -224,12 +233,14 @@ void PackPixels(const PackPixelsParams ¶ms, sizeof(temp) >= sizeof(gl::ColorI), "Unexpected size of gl::Color struct."); + const auto &colorReadFunction = sourceFormat.colorReadFunction; + for (int y = 0; y < params.area.height; ++y) { for (int x = 0; x < params.area.width; ++x) { uint8_t *dest = destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceGLInfo.pixelBytes; // readFunc and writeFunc will be using the same type of color, CopyTexImage // will not allow the copy otherwise. diff --git a/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.h b/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.h index c95292e10de..e0870300097 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/renderer_utils.h @@ -16,6 +16,11 @@ #include "libANGLE/angletypes.h" +namespace angle +{ +struct Format; +} + namespace gl { struct FormatType; @@ -25,6 +30,16 @@ struct InternalFormat; namespace rx { +using MipGenerationFunction = void (*)(size_t sourceWidth, + size_t sourceHeight, + size_t sourceDepth, + const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourceDepthPitch, + uint8_t *destData, + size_t destRowPitch, + size_t destDepthPitch); + typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest); typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest); typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest); @@ -51,9 +66,7 @@ struct PackPixelsParams }; void PackPixels(const PackPixelsParams ¶ms, - const gl::InternalFormat &sourceFormatInfo, - const FastCopyFunctionMap &fastCopyFunctionsMap, - ColorReadFunction colorReadFunction, + const angle::Format &sourceFormat, int inputPitch, const uint8_t *source, uint8_t *destination); @@ -62,6 +75,30 @@ ColorWriteFunction GetColorWriteFunction(const gl::FormatType &formatType); ColorCopyFunction GetFastCopyFunction(const FastCopyFunctionMap &fastCopyFunctions, const gl::FormatType &formatType); +using LoadImageFunction = void (*)(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +struct LoadImageFunctionInfo +{ + LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {} + LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion) + : loadFunction(loadFunction), requiresConversion(requiresConversion) + { + } + + LoadImageFunction loadFunction; + bool requiresConversion; +}; + +using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum); + } // namespace rx #endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_ diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp index b0e01e86c9c..bc16c82e927 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.cpp @@ -22,13 +22,13 @@ BufferVk::~BufferVk() { } -gl::Error BufferVk::setData(const void *data, size_t size, GLenum usage) +gl::Error BufferVk::setData(GLenum target, const void *data, size_t size, GLenum usage) { UNIMPLEMENTED(); return gl::Error(GL_INVALID_OPERATION); } -gl::Error BufferVk::setSubData(const void *data, size_t size, size_t offset) +gl::Error BufferVk::setSubData(GLenum target, const void *data, size_t size, size_t offset) { UNIMPLEMENTED(); return gl::Error(GL_INVALID_OPERATION); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.h b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.h index 19bd61ea383..d0006634522 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/BufferVk.h @@ -21,8 +21,8 @@ class BufferVk : public BufferImpl BufferVk(); ~BufferVk() override; - gl::Error setData(const void *data, size_t size, GLenum usage) override; - gl::Error setSubData(const void *data, size_t size, size_t offset) override; + gl::Error setData(GLenum target, const void *data, size_t size, GLenum usage) override; + gl::Error setSubData(GLenum target, const void *data, size_t size, size_t offset) override; gl::Error copySubData(BufferImpl *source, GLintptr sourceOffset, GLintptr destOffset, diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp index 19d11cce1d1..8bd06330015 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -106,27 +106,10 @@ gl::Error ContextVk::drawRangeElements(GLenum mode, return gl::Error(GL_INVALID_OPERATION); } -void ContextVk::notifyDeviceLost() +GLenum ContextVk::getResetStatus() { UNIMPLEMENTED(); -} - -bool ContextVk::isDeviceLost() const -{ - UNIMPLEMENTED(); - return bool(); -} - -bool ContextVk::testDeviceLost() -{ - UNIMPLEMENTED(); - return bool(); -} - -bool ContextVk::testDeviceResettable() -{ - UNIMPLEMENTED(); - return bool(); + return GL_NO_ERROR; } std::string ContextVk::getVendorString() const @@ -253,9 +236,9 @@ FenceSyncImpl *ContextVk::createFenceSync() return new FenceSyncVk(); } -TransformFeedbackImpl *ContextVk::createTransformFeedback() +TransformFeedbackImpl *ContextVk::createTransformFeedback(const gl::TransformFeedbackState &state) { - return new TransformFeedbackVk(); + return new TransformFeedbackVk(state); } SamplerImpl *ContextVk::createSampler() diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.h b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.h index 05070c996f9..61b4f5b30cb 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ContextVk.h @@ -54,11 +54,8 @@ class ContextVk : public ContextImpl const GLvoid *indices, const gl::IndexRange &indexRange) override; - // TODO(jmadill): Investigate proper impl methods for this. - void notifyDeviceLost() override; - bool isDeviceLost() const override; - bool testDeviceLost() override; - bool testDeviceResettable() override; + // Device loss + GLenum getResetStatus() override; // Vendor and description strings. std::string getVendorString() const override; @@ -111,7 +108,8 @@ class ContextVk : public ContextImpl FenceSyncImpl *createFenceSync() override; // Transform Feedback creation - TransformFeedbackImpl *createTransformFeedback() override; + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; // Sampler object creation SamplerImpl *createSampler() override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp index 8e314a58ae9..95e8ea65307 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.cpp @@ -48,12 +48,6 @@ egl::ConfigSet DisplayVk::generateConfigs() return egl::ConfigSet(); } -bool DisplayVk::isDeviceLost() const -{ - UNIMPLEMENTED(); - return bool(); -} - bool DisplayVk::testDeviceLost() { UNIMPLEMENTED(); @@ -154,6 +148,12 @@ StreamProducerImpl *DisplayVk::createStreamProducerD3DTextureNV12( return static_cast<StreamProducerImpl *>(0); } +gl::Version DisplayVk::getMaxSupportedESVersion() const +{ + UNIMPLEMENTED(); + return gl::Version(0, 0); +} + void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const { UNIMPLEMENTED(); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.h b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.h index 195e9d4e33b..91838980dc3 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/DisplayVk.h @@ -31,7 +31,6 @@ class DisplayVk : public DisplayImpl egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; egl::Error restoreLostDevice() override; @@ -71,6 +70,7 @@ class DisplayVk : public DisplayImpl StreamProducerImpl *createStreamProducerD3DTextureNV12( egl::Stream::ConsumerType consumerType, const egl::AttributeMap &attribs) override; + gl::Version getMaxSupportedESVersion() const override; private: void generateExtensions(egl::DisplayExtensions *outExtensions) const override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp index e2b3a700a16..591cf062c53 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.cpp @@ -201,4 +201,12 @@ bool ProgramVk::getUniformBlockMemberInfo(const std::string &memberUniformName, return bool(); } +void ProgramVk::setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + UNIMPLEMENTED(); +} + } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.h b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.h index 403a3963af6..8d8a1f7ca4e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ProgramVk.h @@ -88,6 +88,11 @@ class ProgramVk : public ProgramImpl // Returns false for inactive members. bool getUniformBlockMemberInfo(const std::string &memberUniformName, sh::BlockMemberInfo *memberInfoOut) const override; + + void setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) override; }; } // namespace rx diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.cpp index 06355c3c8e1..8bece9b454e 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.cpp @@ -22,8 +22,8 @@ ShaderVk::~ShaderVk() { } -int ShaderVk::prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string *sourcePath) +ShCompileOptions ShaderVk::prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) { UNIMPLEMENTED(); return int(); diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.h b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.h index f847070c4b0..1d713caf88b 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/ShaderVk.h @@ -22,8 +22,8 @@ class ShaderVk : public ShaderImpl ~ShaderVk() override; // Returns additional ShCompile options. - int prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string *sourcePath) override; + ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) override; // Returns success for compiling on the driver. Returns success. bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override; diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp index 782f11f1e42..ea445c75306 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp @@ -14,7 +14,8 @@ namespace rx { -TransformFeedbackVk::TransformFeedbackVk() : TransformFeedbackImpl() +TransformFeedbackVk::TransformFeedbackVk(const gl::TransformFeedbackState &state) + : TransformFeedbackImpl(state) { } diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h index 6702f6b300d..ed8522c9c44 100644 --- a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h +++ b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h @@ -18,7 +18,7 @@ namespace rx class TransformFeedbackVk : public TransformFeedbackImpl { public: - TransformFeedbackVk(); + TransformFeedbackVk(const gl::TransformFeedbackState &state); ~TransformFeedbackVk() override; void begin(GLenum primitiveMode) override; diff --git a/chromium/third_party/angle/src/libANGLE/signal_utils.cpp b/chromium/third_party/angle/src/libANGLE/signal_utils.cpp index 0c912321a2a..62d45b953fc 100644 --- a/chromium/third_party/angle/src/libANGLE/signal_utils.cpp +++ b/chromium/third_party/angle/src/libANGLE/signal_utils.cpp @@ -9,6 +9,8 @@ #include "libANGLE/signal_utils.h" +#include <algorithm> + #include "common/debug.h" namespace angle @@ -25,14 +27,15 @@ BroadcastChannel::~BroadcastChannel() void BroadcastChannel::addReceiver(ChannelBinding *receiver) { - ASSERT(mReceivers.count(receiver) == 0); - mReceivers.insert(receiver); + ASSERT(std::find(mReceivers.begin(), mReceivers.end(), receiver) == mReceivers.end()); + mReceivers.push_back(receiver); } void BroadcastChannel::removeReceiver(ChannelBinding *receiver) { - ASSERT(mReceivers.count(receiver) == 1); - mReceivers.erase(receiver); + auto iter = std::find(mReceivers.begin(), mReceivers.end(), receiver); + ASSERT(iter != mReceivers.end()); + mReceivers.erase(iter); } void BroadcastChannel::signal() const diff --git a/chromium/third_party/angle/src/libANGLE/signal_utils.h b/chromium/third_party/angle/src/libANGLE/signal_utils.h index f87b927f0ad..835f2c602d2 100644 --- a/chromium/third_party/angle/src/libANGLE/signal_utils.h +++ b/chromium/third_party/angle/src/libANGLE/signal_utils.h @@ -46,7 +46,7 @@ class BroadcastChannel final : NonCopyable void addReceiver(ChannelBinding *receiver); void removeReceiver(ChannelBinding *receiver); - std::set<ChannelBinding *> mReceivers; + std::vector<ChannelBinding *> mReceivers; }; // The dependent class keeps bindings to the host's BroadcastChannel. diff --git a/chromium/third_party/angle/src/libANGLE/validationEGL.cpp b/chromium/third_party/angle/src/libANGLE/validationEGL.cpp index d97ecd87c37..139ec18a168 100644 --- a/chromium/third_party/angle/src/libANGLE/validationEGL.cpp +++ b/chromium/third_party/angle/src/libANGLE/validationEGL.cpp @@ -17,6 +17,7 @@ #include "libANGLE/Stream.h" #include "libANGLE/Surface.h" #include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" #include <EGL/eglext.h> @@ -58,7 +59,7 @@ bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::T for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++) { - if (texture->getInternalFormat(face, level) != GL_NONE) + if (texture->getFormat(face, level).valid()) { return true; } @@ -66,7 +67,7 @@ bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::T } else { - if (texture->getInternalFormat(texture->getTarget(), level) != GL_NONE) + if (texture->getFormat(texture->getTarget(), level).valid()) { return true; } @@ -81,7 +82,7 @@ bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture) ASSERT(texture->getTarget() == GL_TEXTURE_CUBE_MAP); for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++) { - if (texture->getInternalFormat(face, 0) == GL_NONE) + if (!texture->getFormat(face, 0).valid()) { return true; } @@ -173,6 +174,11 @@ Error ValidateDisplay(const Display *display) return Error(EGL_NOT_INITIALIZED, "display is not initialized."); } + if (display->isDeviceLost()) + { + return Error(EGL_CONTEXT_LOST, "display had a context loss"); + } + return Error(EGL_SUCCESS); } @@ -321,19 +327,68 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context } break; + case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE: + if (!display->getExtensions().createContextWebGLCompatibility) + { + return Error(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE requires " + "EGL_ANGLE_create_context_webgl_compatibility."); + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return Error( + EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE must be EGL_TRUE or EGL_FALSE."); + } + break; + + case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM: + if (!display->getExtensions().createContextBindGeneratesResource) + { + return Error(EGL_BAD_ATTRIBUTE, + "Attribute EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM requires " + "EGL_CHROMIUM_create_context_bind_generates_resource."); + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return Error(EGL_BAD_ATTRIBUTE, + "EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM must be EGL_TRUE or " + "EGL_FALSE."); + } + break; + default: return Error(EGL_BAD_ATTRIBUTE); } } - if ((clientMajorVersion != 2 && clientMajorVersion != 3) || clientMinorVersion != 0) + switch (clientMajorVersion) { - return Error(EGL_BAD_CONFIG); - } - - if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR)) - { - return Error(EGL_BAD_CONFIG); + case 2: + if (clientMinorVersion != 0) + { + return Error(EGL_BAD_CONFIG); + } + break; + case 3: + if (clientMinorVersion != 0 && clientMinorVersion != 1) + { + return Error(EGL_BAD_CONFIG); + } + if (!(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR)) + { + return Error(EGL_BAD_CONFIG); + } + if (display->getMaxSupportedESVersion() < + gl::Version(static_cast<GLuint>(clientMajorVersion), + static_cast<GLuint>(clientMinorVersion))) + { + return Error(EGL_BAD_CONFIG, "Requested GLES version is not supported."); + } + break; + default: + return Error(EGL_BAD_CONFIG); + break; } // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES @@ -368,7 +423,8 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context return Error(EGL_BAD_MATCH); } - if (shareContext->getClientVersion() != clientMajorVersion) + if (shareContext->getClientMajorVersion() != clientMajorVersion || + shareContext->getClientMinorVersion() != clientMinorVersion) { return Error(EGL_BAD_CONTEXT); } @@ -1439,6 +1495,8 @@ Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display, const Stream *stream, const AttributeMap &attribs) { + ANGLE_TRY(ValidateDisplay(display)); + const DisplayExtensions &displayExtensions = display->getExtensions(); if (!displayExtensions.streamProducerD3DTextureNV12) { diff --git a/chromium/third_party/angle/src/libANGLE/validationES.cpp b/chromium/third_party/angle/src/libANGLE/validationES.cpp index f96ad6d9e77..fff9088f7fa 100644 --- a/chromium/third_party/angle/src/libANGLE/validationES.cpp +++ b/chromium/third_party/angle/src/libANGLE/validationES.cpp @@ -99,41 +99,89 @@ bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxV return true; } -} // anonymous namespace +bool ValidReadPixelsFormatType(ValidationContext *context, + GLenum framebufferComponentType, + GLenum format, + GLenum type) +{ + switch (framebufferComponentType) + { + case GL_UNSIGNED_NORMALIZED: + // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use + // ReadPixels with BGRA even if the extension is not present + return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) || + (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT && + type == GL_UNSIGNED_BYTE); + + case GL_SIGNED_NORMALIZED: + return (format == GL_RGBA && type == GL_UNSIGNED_BYTE); -bool ValidCap(const Context *context, GLenum cap) + case GL_INT: + return (format == GL_RGBA_INTEGER && type == GL_INT); + + case GL_UNSIGNED_INT: + return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT); + + case GL_FLOAT: + return (format == GL_RGBA && type == GL_FLOAT); + + default: + UNREACHABLE(); + return false; + } +} + +bool ValidCap(const Context *context, GLenum cap, bool queryOnly) { switch (cap) { - // EXT_multisample_compatibility - case GL_MULTISAMPLE_EXT: - case GL_SAMPLE_ALPHA_TO_ONE_EXT: - return context->getExtensions().multisampleCompatibility; - - case GL_CULL_FACE: - case GL_POLYGON_OFFSET_FILL: - case GL_SAMPLE_ALPHA_TO_COVERAGE: - case GL_SAMPLE_COVERAGE: - case GL_SCISSOR_TEST: - case GL_STENCIL_TEST: - case GL_DEPTH_TEST: - case GL_BLEND: - case GL_DITHER: - return true; + // EXT_multisample_compatibility + case GL_MULTISAMPLE_EXT: + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + return context->getExtensions().multisampleCompatibility; + + case GL_CULL_FACE: + case GL_POLYGON_OFFSET_FILL: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_COVERAGE: + case GL_SCISSOR_TEST: + case GL_STENCIL_TEST: + case GL_DEPTH_TEST: + case GL_BLEND: + case GL_DITHER: + return true; - case GL_PRIMITIVE_RESTART_FIXED_INDEX: - case GL_RASTERIZER_DISCARD: - return (context->getClientVersion() >= 3); + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_RASTERIZER_DISCARD: + return (context->getClientMajorVersion() >= 3); - case GL_DEBUG_OUTPUT_SYNCHRONOUS: - case GL_DEBUG_OUTPUT: - return context->getExtensions().debug; + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + case GL_DEBUG_OUTPUT: + return context->getExtensions().debug; - default: + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + return queryOnly && context->getExtensions().bindGeneratesResource; + + default: + return false; + } +} + +bool ValidateRobustBufferSize(ValidationContext *context, GLsizei bufSize, GLsizei numParams) +{ + if (bufSize < numParams) + { + context->handleError(Error(GL_INVALID_OPERATION, + "%u parameters are required but %i were provided.", numParams, + bufSize)); return false; } + + return true; } +} // anonymous namespace + bool ValidTextureTarget(const ValidationContext *context, GLenum target) { switch (target) @@ -144,7 +192,7 @@ bool ValidTextureTarget(const ValidationContext *context, GLenum target) case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: - return (context->getClientVersion() >= 3); + return (context->getClientMajorVersion() >= 3); default: return false; @@ -170,7 +218,7 @@ bool ValidTexture3DTarget(const ValidationContext *context, GLenum target) { case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: - return (context->getClientVersion() >= 3); + return (context->getClientMajorVersion() >= 3); default: return false; @@ -233,7 +281,7 @@ bool ValidFramebufferTarget(GLenum target) } } -bool ValidBufferTarget(const Context *context, GLenum target) +bool ValidBufferTarget(const ValidationContext *context, GLenum target) { switch (target) { @@ -243,21 +291,25 @@ bool ValidBufferTarget(const Context *context, GLenum target) case GL_PIXEL_PACK_BUFFER: case GL_PIXEL_UNPACK_BUFFER: - return (context->getExtensions().pixelBufferObject || context->getClientVersion() >= 3); + return (context->getExtensions().pixelBufferObject || + context->getClientMajorVersion() >= 3); case GL_COPY_READ_BUFFER: case GL_COPY_WRITE_BUFFER: case GL_TRANSFORM_FEEDBACK_BUFFER: case GL_UNIFORM_BUFFER: - return (context->getClientVersion() >= 3); + return (context->getClientMajorVersion() >= 3); default: return false; } } -bool ValidBufferParameter(const Context *context, GLenum pname) +bool ValidBufferParameter(const ValidationContext *context, GLenum pname, GLsizei *numParams) { + // All buffer parameter queries return one value. + *numParams = 1; + const Extensions &extensions = context->getExtensions(); switch (pname) @@ -271,14 +323,15 @@ bool ValidBufferParameter(const Context *context, GLenum pname) case GL_BUFFER_MAPPED: static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal."); - return (context->getClientVersion() >= 3) || extensions.mapBuffer || extensions.mapBufferRange; + return (context->getClientMajorVersion() >= 3) || extensions.mapBuffer || + extensions.mapBufferRange; // GL_BUFFER_MAP_POINTER is a special case, and may only be // queried with GetBufferPointerv case GL_BUFFER_ACCESS_FLAGS: case GL_BUFFER_MAP_OFFSET: case GL_BUFFER_MAP_LENGTH: - return (context->getClientVersion() >= 3) || extensions.mapBufferRange; + return (context->getClientMajorVersion() >= 3) || extensions.mapBufferRange; default: return false; @@ -392,6 +445,74 @@ bool ValidCompressedImageSize(const ValidationContext *context, return true; } +bool ValidImageDataSize(ValidationContext *context, + GLenum textureTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum internalFormat, + GLenum type, + const GLvoid *pixels, + GLsizei imageSize) +{ + gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER); + if (pixelUnpackBuffer == nullptr && imageSize < 0) + { + // Checks are not required + return true; + } + + // ...the data would be unpacked from the buffer object such that the memory reads required + // would exceed the data store size. + GLenum sizedFormat = GetSizedInternalFormat(internalFormat, type); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat); + const gl::Extents size(width, height, depth); + const auto &unpack = context->getGLState().getUnpackState(); + + bool targetIs3D = textureTarget == GL_TEXTURE_3D || textureTarget == GL_TEXTURE_2D_ARRAY; + auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D); + if (endByteOrErr.isError()) + { + context->handleError(endByteOrErr.getError()); + return false; + } + + GLuint endByte = endByteOrErr.getResult(); + + if (pixelUnpackBuffer) + { + CheckedNumeric<size_t> checkedEndByte(endByteOrErr.getResult()); + CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels)); + checkedEndByte += checkedOffset; + + if (!checkedEndByte.IsValid() || + (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize()))) + { + // Overflow past the end of the buffer + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + } + else + { + ASSERT(imageSize >= 0); + if (pixels == nullptr && imageSize != 0) + { + context->handleError( + Error(GL_INVALID_OPERATION, "imageSize must be 0 if no texture data is provided.")); + } + + if (endByte > static_cast<GLuint>(imageSize)) + { + context->handleError( + Error(GL_INVALID_OPERATION, "imageSize must be at least %u.", endByte)); + return false; + } + } + + return true; +} + bool ValidQueryType(const Context *context, GLenum queryType) { static_assert(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT, "GL extension enums not equal."); @@ -403,7 +524,7 @@ bool ValidQueryType(const Context *context, GLenum queryType) case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: return true; case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: - return (context->getClientVersion() >= 3); + return (context->getClientMajorVersion() >= 3); case GL_TIME_ELAPSED_EXT: return context->getExtensions().disjointTimerQuery; case GL_COMMANDS_COMPLETED_CHROMIUM: @@ -477,19 +598,20 @@ bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment) { case GL_DEPTH_ATTACHMENT: case GL_STENCIL_ATTACHMENT: - break; + break; case GL_DEPTH_STENCIL_ATTACHMENT: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return false; - } - break; + if (!context->getExtensions().webglCompatibility && + context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; default: context->handleError(Error(GL_INVALID_ENUM)); - return false; + return false; } } @@ -565,7 +687,7 @@ bool ValidateRenderbufferStorageParametersANGLE(gl::Context *context, GLenum tar // the specified storage. This is different than ES 3.0 in which a sample number higher // than the maximum sample number supported by this format generates a GL_INVALID_VALUE. // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3. - if (context->getClientVersion() >= 3) + if (context->getClientMajorVersion() >= 3) { const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples()) @@ -706,8 +828,7 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, if (readColorBuffer && drawColorBuffer) { - GLenum readInternalFormat = readColorBuffer->getInternalFormat(); - const InternalFormat &readFormatInfo = GetInternalFormatInfo(readInternalFormat); + const Format &readFormat = readColorBuffer->getFormat(); for (size_t drawbufferIdx = 0; drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx) @@ -716,8 +837,7 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, drawFramebuffer->getDrawBuffer(drawbufferIdx); if (attachment) { - GLenum drawInternalFormat = attachment->getInternalFormat(); - const InternalFormat &drawFormatInfo = GetInternalFormatInfo(drawInternalFormat); + const Format &drawFormat = attachment->getFormat(); // The GL ES 3.0.2 spec (pg 193) states that: // 1) If the read buffer is fixed point format, the draw buffer must be as well @@ -725,8 +845,8 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, // 3) If the read buffer is a signed integer format, the draw buffer must be as well // Changes with EXT_color_buffer_float: // Case 1) is changed to fixed point OR floating point - GLenum readComponentType = readFormatInfo.componentType; - GLenum drawComponentType = drawFormatInfo.componentType; + GLenum readComponentType = readFormat.info->componentType; + GLenum drawComponentType = drawFormat.info->componentType; bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED || readComponentType == GL_SIGNED_NORMALIZED); bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED || @@ -767,7 +887,8 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, return false; } - if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds)) + if (readColorBuffer->getSamples() > 0 && + (!Format::SameSized(readFormat, drawFormat) || !sameBounds)) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -775,7 +896,9 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, } } - if ((readFormatInfo.componentType == GL_INT || readFormatInfo.componentType == GL_UNSIGNED_INT) && filter == GL_LINEAR) + if ((readFormat.info->componentType == GL_INT || + readFormat.info->componentType == GL_UNSIGNED_INT) && + filter == GL_LINEAR) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -794,7 +917,7 @@ bool ValidateBlitFramebufferParameters(ValidationContext *context, if (readBuffer && drawBuffer) { - if (readBuffer->getInternalFormat() != drawBuffer->getInternalFormat()) + if (!Format::SameSized(readBuffer->getFormat(), drawBuffer->getFormat())) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -823,26 +946,26 @@ bool ValidateGetVertexAttribParameters(Context *context, GLenum pname) case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: case GL_CURRENT_VERTEX_ATTRIB: - return true; + return true; case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: - // Don't verify ES3 context because GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE uses - // the same constant. - static_assert(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, - "ANGLE extension enums not equal to GL enums."); - return true; + // Don't verify ES3 context because GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE uses + // the same constant. + static_assert(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, + "ANGLE extension enums not equal to GL enums."); + return true; case GL_VERTEX_ATTRIB_ARRAY_INTEGER: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return false; - } - return true; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + return true; default: context->handleError(Error(GL_INVALID_ENUM)); - return false; + return false; } } @@ -861,19 +984,19 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pnam case GL_TEXTURE_COMPARE_FUNC: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return false; - } - if (target == GL_TEXTURE_EXTERNAL_OES && !context->getExtensions().eglImageExternalEssl3) - { - context->handleError(Error(GL_INVALID_ENUM, - "ES3 texture parameters are not available without " - "GL_OES_EGL_image_external_essl3.")); - return false; - } - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + if (target == GL_TEXTURE_EXTERNAL_OES && !context->getExtensions().eglImageExternalEssl3) + { + context->handleError(Error(GL_INVALID_ENUM, + "ES3 texture parameters are not available without " + "GL_OES_EGL_image_external_essl3.")); + return false; + } + break; default: break; } @@ -1101,6 +1224,13 @@ bool ValidateReadPixels(ValidationContext *context, const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); ASSERT(framebuffer); + + if (framebuffer->getReadBufferState() == GL_NONE) + { + context->handleError(Error(GL_INVALID_OPERATION, "Read buffer is GL_NONE")); + return false; + } + const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer(); if (!readBuffer) { @@ -1110,18 +1240,56 @@ bool ValidateReadPixels(ValidationContext *context, GLenum currentFormat = framebuffer->getImplementationColorReadFormat(); GLenum currentType = framebuffer->getImplementationColorReadType(); - GLenum currentInternalFormat = readBuffer->getInternalFormat(); - GLuint clientVersion = context->getClientVersion(); + GLenum currentInternalFormat = readBuffer->getFormat().asSized(); - bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) : - ValidES3ReadFormatType(context, currentInternalFormat, format, type); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(currentInternalFormat); + bool validFormatTypeCombination = + ValidReadPixelsFormatType(context, internalFormatInfo.componentType, format, type); - if (!(currentFormat == format && currentType == type) && !validReadFormat) + if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination) { context->handleError(Error(GL_INVALID_OPERATION)); return false; } + // Check for pixel pack buffer related API errors + gl::Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_PACK_BUFFER); + if (pixelPackBuffer != nullptr) + { + // .. the data would be packed to the buffer object such that the memory writes required + // would exceed the data store size. + GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); + const InternalFormat &formatInfo = GetInternalFormatInfo(sizedInternalFormat); + const gl::Extents size(width, height, 1); + const auto &pack = context->getGLState().getPackState(); + + auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, pack, false); + if (endByteOrErr.isError()) + { + context->handleError(endByteOrErr.getError()); + return false; + } + + CheckedNumeric<size_t> checkedEndByte(endByteOrErr.getResult()); + CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels)); + checkedEndByte += checkedOffset; + + if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize())) + { + // Overflow past the end of the buffer + context->handleError( + Error(GL_INVALID_OPERATION, "Writes would overflow the pixel pack buffer.")); + return false; + } + + // ...the buffer object's data store is currently mapped. + if (pixelPackBuffer->isMapped()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Pixel pack buffer is mapped.")); + return false; + } + } + return true; } @@ -1142,30 +1310,20 @@ bool ValidateReadnPixelsEXT(Context *context, } GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); - const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat); - - auto outputPitchOrErr = - sizedFormatInfo.computeRowPitch(type, width, context->getGLState().getPackAlignment(), - context->getGLState().getPackRowLength()); + const InternalFormat &formatInfo = GetInternalFormatInfo(sizedInternalFormat); + const gl::Extents size(width, height, 1); + const auto &pack = context->getGLState().getPackState(); - if (outputPitchOrErr.isError()) + auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, pack, false); + if (endByteOrErr.isError()) { - context->handleError(outputPitchOrErr.getError()); + context->handleError(endByteOrErr.getError()); return false; } - CheckedNumeric<GLuint> checkedOutputPitch(outputPitchOrErr.getResult()); - auto checkedRequiredSize = checkedOutputPitch * height; - if (!checkedRequiredSize.IsValid()) + if (endByteOrErr.getResult() > static_cast<GLuint>(bufSize)) { - context->handleError(Error(GL_INVALID_OPERATION, "Unsigned multiplication overflow.")); - return false; - } - - // sized query sanity check - if (checkedRequiredSize.ValueOrDie() > static_cast<GLuint>(bufSize)) - { - context->handleError(Error(GL_INVALID_OPERATION)); + context->handleError(Error(GL_INVALID_OPERATION, "Writes would overflow past bufSize.")); return false; } @@ -1488,7 +1646,8 @@ static bool ValidateUniformCommonBase(gl::Context *context, bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count) { // Check for ES3 uniform entry points - if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3) + if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && + context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1517,13 +1676,13 @@ bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint locati // Check for ES3 uniform entry points int rows = VariableRowCount(matrixType); int cols = VariableColumnCount(matrixType); - if (rows != cols && context->getClientVersion() < 3) + if (rows != cols && context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; } - if (transpose != GL_FALSE && context->getClientVersion() < 3) + if (transpose != GL_FALSE && context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_VALUE)); return false; @@ -1576,10 +1735,12 @@ bool ValidateStateQuery(ValidationContext *context, case GL_TEXTURE_BINDING_2D_ARRAY: break; case GL_TEXTURE_BINDING_EXTERNAL_OES: - if (!context->getExtensions().eglStreamConsumerExternal) + if (!context->getExtensions().eglStreamConsumerExternal && + !context->getExtensions().eglImageExternal) { - context->handleError( - Error(GL_INVALID_ENUM, "NV_EGL_stream_consumer_external extension not enabled")); + context->handleError(Error(GL_INVALID_ENUM, + "Neither NV_EGL_stream_consumer_external nor " + "GL_OES_EGL_image_external extensions enabled")); return false; } break; @@ -1596,6 +1757,13 @@ bool ValidateStateQuery(ValidationContext *context, const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); ASSERT(framebuffer); + + if (framebuffer->getReadBufferState() == GL_NONE) + { + context->handleError(Error(GL_INVALID_OPERATION, "Read buffer is GL_NONE")); + return false; + } + const FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); if (!attachment) { @@ -1610,7 +1778,31 @@ bool ValidateStateQuery(ValidationContext *context, } // pname is valid, but there are no parameters to return - if (numParams == 0) + if (*numParams == 0) + { + return false; + } + + return true; +} + +bool ValidateRobustStateQuery(ValidationContext *context, + GLenum pname, + GLsizei bufSize, + GLenum *nativeType, + unsigned int *numParams) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateStateQuery(context, pname, nativeType, numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *numParams)) { return false; } @@ -1631,7 +1823,7 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, GLsizei width, GLsizei height, GLint border, - GLenum *textureFormatOut) + Format *textureFormatOut) { if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0) { @@ -1671,6 +1863,12 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, return false; } + if (readFramebuffer->getReadBufferState() == GL_NONE) + { + context->handleError(Error(GL_INVALID_OPERATION, "Read buffer is GL_NONE")); + return false; + } + const gl::Caps &caps = context->getCaps(); GLuint maxDimension = 0; @@ -1748,7 +1946,7 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, return false; } - if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + if (!formatInfo.textureSupport(context->getClientMajorVersion(), context->getExtensions())) { context->handleError(Error(GL_INVALID_ENUM)); return false; @@ -1762,7 +1960,10 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, } } - *textureFormatOut = texture->getInternalFormat(target, level); + if (textureFormatOut) + { + *textureFormatOut = texture->getFormat(target, level); + } return true; } @@ -1980,17 +2181,17 @@ bool ValidateDrawElements(ValidationContext *context, { case GL_UNSIGNED_BYTE: case GL_UNSIGNED_SHORT: - break; + break; case GL_UNSIGNED_INT: - if (context->getClientVersion() < 3 && !context->getExtensions().elementIndexUint) - { - context->handleError(Error(GL_INVALID_ENUM)); - return false; - } - break; + if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; default: context->handleError(Error(GL_INVALID_ENUM)); - return false; + return false; } const State &state = context->getGLState(); @@ -2178,7 +2379,8 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach GLenum textarget, GLuint texture, GLint level) { // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap extension - if (context->getClientVersion() < 3 && !context->getExtensions().fboRenderMipmap && level != 0) + if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap && + level != 0) { context->handleError(Error(GL_INVALID_VALUE)); return false; @@ -2238,8 +2440,8 @@ bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attach return false; } - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(tex->getInternalFormat(textarget, level)); - if (internalFormatInfo.compressed) + const Format &format = tex->getFormat(textarget, level); + if (format.info->compressed) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -2466,7 +2668,7 @@ bool ValidateEGLImageTargetTexture2DOES(Context *context, return false; } - const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat()); + const TextureCaps &textureCaps = context->getTextureCaps().get(image->getFormat().asSized()); if (!textureCaps.texturable) { context->handleError(Error(GL_INVALID_OPERATION, @@ -2504,7 +2706,7 @@ bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context, return false; } - const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat()); + const TextureCaps &textureCaps = context->getTextureCaps().get(image->getFormat().asSized()); if (!textureCaps.renderable) { context->handleError(Error( @@ -2644,13 +2846,13 @@ bool ValidateCopyTexImage2D(ValidationContext *context, GLsizei height, GLint border) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0, 0, x, y, width, height, border); } - ASSERT(context->getClientVersion() == 3); + ASSERT(context->getClientMajorVersion() == 3); return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0, 0, x, y, width, height, border); } @@ -2755,7 +2957,7 @@ bool ValidateCopyTexSubImage2D(Context *context, GLsizei width, GLsizei height) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, x, y, width, height, 0); @@ -2975,10 +3177,9 @@ bool ValidateGenerateMipmap(Context *context, GLenum target) return false; } - GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target; - GLenum internalFormat = texture->getInternalFormat(baseTarget, effectiveBaseLevel); - const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat); + GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target; + const auto &format = texture->getFormat(baseTarget, effectiveBaseLevel); + const TextureCaps &formatCaps = context->getTextureCaps().get(format.asSized()); // GenerateMipmap should not generate an INVALID_OPERATION for textures created with // unsized formats or that are color renderable and filterable. Since we do not track if @@ -2988,18 +3189,15 @@ bool ValidateGenerateMipmap(Context *context, GLenum target) // textures since they're the only texture format that can be created with unsized formats // that is not color renderable. New unsized formats are unlikely to be added, since ES2 // was the last version to use add them. - bool isLUMA = internalFormat == GL_LUMINANCE8_EXT || - internalFormat == GL_LUMINANCE8_ALPHA8_EXT || internalFormat == GL_ALPHA8_EXT; - - if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0 || !formatCaps.filterable || - (!formatCaps.renderable && !isLUMA) || formatInfo.compressed) + if (format.info->depthBits > 0 || format.info->stencilBits > 0 || !formatCaps.filterable || + (!formatCaps.renderable && !format.info->isLUMA()) || format.info->compressed) { context->handleError(Error(GL_INVALID_OPERATION)); return false; } // GL_EXT_sRGB does not support mipmap generation on sRGB textures - if (context->getClientVersion() == 2 && formatInfo.colorEncoding == GL_SRGB) + if (context->getClientMajorVersion() == 2 && format.info->colorEncoding == GL_SRGB) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -3010,7 +3208,7 @@ bool ValidateGenerateMipmap(Context *context, GLenum target) (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) || !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0))))) { - ASSERT(context->getClientVersion() <= 2 && + ASSERT(context->getClientMajorVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP)); context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -3076,4 +3274,452 @@ bool ValidateGenOrDelete(Context *context, GLint n) return true; } +bool ValidateEnable(Context *context, GLenum cap) +{ + if (!ValidCap(context, cap, false)) + { + context->handleError(Error(GL_INVALID_ENUM, "Invalid cap.")); + return false; + } + + if (context->getLimitations().noSampleAlphaToCoverageSupport && + cap == GL_SAMPLE_ALPHA_TO_COVERAGE) + { + const char *errorMessage = "Current renderer doesn't support alpha-to-coverage"; + context->handleError(Error(GL_INVALID_OPERATION, errorMessage)); + + // We also output an error message to the debugger window if tracing is active, so that + // developers can see the error message. + ERR("%s", errorMessage); + return false; + } + + return true; +} + +bool ValidateDisable(Context *context, GLenum cap) +{ + if (!ValidCap(context, cap, false)) + { + context->handleError(Error(GL_INVALID_ENUM, "Invalid cap.")); + return false; + } + + return true; +} + +bool ValidateIsEnabled(Context *context, GLenum cap) +{ + if (!ValidCap(context, cap, true)) + { + context->handleError(Error(GL_INVALID_ENUM, "Invalid cap.")); + return false; + } + + return true; +} + +bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize) +{ + if (!context->getExtensions().robustClientMemory) + { + context->handleError( + Error(GL_INVALID_OPERATION, "GL_ANGLE_robust_client_memory is not available.")); + return false; + } + + if (bufSize < 0) + { + context->handleError(Error(GL_INVALID_VALUE, "bufSize cannot be negative.")); + return false; + } + + return true; +} + +bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei *numParams) +{ + // Only one parameter is returned from glGetFramebufferAttachmentParameteriv + *numParams = 1; + + if (!ValidFramebufferTarget(target)) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + int clientVersion = context->getClientMajorVersion(); + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + if (clientVersion < 3 && !context->getExtensions().sRGB) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (clientVersion < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + default: + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + // Determine if the attachment is a valid enum + switch (attachment) + { + case GL_BACK: + case GL_FRONT: + case GL_DEPTH: + case GL_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: + if (clientVersion < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + default: + if (attachment < GL_COLOR_ATTACHMENT0_EXT || + (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + } + + const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->id() == 0) + { + if (clientVersion < 3) + { + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + + switch (attachment) + { + case GL_BACK: + case GL_DEPTH: + case GL_STENCIL: + break; + + default: + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + } + else + { + if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + { + // Valid attachment query + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + case GL_DEPTH_STENCIL_ATTACHMENT: + if (!framebuffer->hasValidDepthStencil()) + { + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + break; + + default: + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + } + } + + const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment); + if (attachmentObject) + { + ASSERT(attachmentObject->type() == GL_RENDERBUFFER || + attachmentObject->type() == GL_TEXTURE || + attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT); + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (attachmentObject->type() != GL_RENDERBUFFER && + attachmentObject->type() != GL_TEXTURE) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + if (attachmentObject->type() != GL_TEXTURE) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + if (attachmentObject->type() != GL_TEXTURE) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) + { + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (attachmentObject->type() != GL_TEXTURE) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + default: + break; + } + } + else + { + // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + // is NONE, then querying any other pname will generate INVALID_ENUM. + + // ES 3.0.2 spec pg 235 states that if the attachment type is none, + // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an + // INVALID_OPERATION for all other pnames + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (clientVersion < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + default: + if (clientVersion < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + else + { + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + } + } + + return true; +} + +bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetFramebufferAttachmentParameteriv(context, target, attachment, pname, numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *numParams)) + { + return false; + } + + return true; +} + +bool ValidateGetBufferParameteriv(ValidationContext *context, + GLenum target, + GLenum pname, + GLsizei *numParams) +{ + // Initialize result + *numParams = 0; + + if (!ValidBufferTarget(context, target)) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + if (!ValidBufferParameter(context, pname, numParams)) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + if (context->getGLState().getTargetBuffer(target) == nullptr) + { + // A null buffer means that "0" is bound to the requested buffer target + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + + return true; +} + +bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetBufferParameteriv(context, target, pname, numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *numParams)) + { + return false; + } + + return true; +} + +bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLsizei *numParams) +{ + // Currently, all GetProgramiv queries return 1 parameter + *numParams = 1; + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + switch (pname) + { + case GL_DELETE_STATUS: + case GL_LINK_STATUS: + case GL_VALIDATE_STATUS: + case GL_INFO_LOG_LENGTH: + case GL_ATTACHED_SHADERS: + case GL_ACTIVE_ATTRIBUTES: + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + case GL_ACTIVE_UNIFORMS: + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + break; + + case GL_PROGRAM_BINARY_LENGTH: + if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary) + { + context->handleError(Error(GL_INVALID_ENUM, + "Querying GL_PROGRAM_BINARY_LENGTH requires " + "GL_OES_get_program_binary or ES 3.0.")); + return false; + } + break; + + case GL_ACTIVE_UNIFORM_BLOCKS: + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + case GL_TRANSFORM_FEEDBACK_VARYINGS: + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM, "Querying requires at least ES 3.0.")); + return false; + } + break; + + default: + context->handleError(Error(GL_INVALID_ENUM, "Unknown parameter name.")); + return false; + } + + return true; +} + +bool ValidateGetProgramivRobustANGLE(Context *context, + GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetProgramiv(context, program, pname, numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *numParams)) + { + return false; + } + + return true; +} + } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/validationES.h b/chromium/third_party/angle/src/libANGLE/validationES.h index 56f88cb4f14..7b7663beb66 100644 --- a/chromium/third_party/angle/src/libANGLE/validationES.h +++ b/chromium/third_party/angle/src/libANGLE/validationES.h @@ -13,6 +13,7 @@ #include <GLES2/gl2.h> #include <GLES3/gl3.h> +#include <GLES3/gl31.h> namespace egl { @@ -23,11 +24,11 @@ class Image; namespace gl { class Context; +struct Format; class Program; class Shader; class ValidationContext; -bool ValidCap(const Context *context, GLenum cap); bool ValidTextureTarget(const ValidationContext *context, GLenum target); bool ValidTexture2DTarget(const ValidationContext *context, GLenum target); bool ValidTexture3DTarget(const ValidationContext *context, GLenum target); @@ -35,8 +36,8 @@ bool ValidTextureExternalTarget(const ValidationContext *context, GLenum target) bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum target); bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target); bool ValidFramebufferTarget(GLenum target); -bool ValidBufferTarget(const Context *context, GLenum target); -bool ValidBufferParameter(const Context *context, GLenum pname); +bool ValidBufferTarget(const ValidationContext *context, GLenum target); +bool ValidBufferParameter(const ValidationContext *context, GLenum pname, GLsizei *numParams); bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level); bool ValidImageSizeParameters(const Context *context, GLenum target, @@ -49,6 +50,16 @@ bool ValidCompressedImageSize(const ValidationContext *context, GLenum internalFormat, GLsizei width, GLsizei height); +bool ValidImageDataSize(ValidationContext *context, + GLenum textureTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum internalFormat, + GLenum type, + const GLvoid *pixels, + GLsizei imageSize); + bool ValidQueryType(const Context *context, GLenum queryType); // Returns valid program if id is a valid program name @@ -130,6 +141,12 @@ bool ValidateStateQuery(ValidationContext *context, GLenum *nativeType, unsigned int *numParams); +bool ValidateRobustStateQuery(ValidationContext *context, + GLenum pname, + GLsizei bufSize, + GLenum *nativeType, + unsigned int *numParams); + bool ValidateCopyTexImageParametersBase(ValidationContext *context, GLenum target, GLint level, @@ -143,7 +160,7 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, GLsizei width, GLsizei height, GLint border, - GLenum *textureInternalFormatOut); + Format *textureFormatOut); bool ValidateDrawArrays(ValidationContext *context, GLenum mode, @@ -268,6 +285,41 @@ bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *textures); bool ValidateGenOrDelete(Context *context, GLint n); +bool ValidateEnable(Context *context, GLenum cap); +bool ValidateDisable(Context *context, GLenum cap); +bool ValidateIsEnabled(Context *context, GLenum cap); + +bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize); + +bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei *numParams); +bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams); + +bool ValidateGetBufferParameteriv(ValidationContext *context, + GLenum target, + GLenum pname, + GLsizei *numParams); +bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams); + +bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLsizei *numParams); +bool ValidateGetProgramivRobustANGLE(Context *context, + GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams); + // Error messages shared here for use in testing. extern const char *g_ExceedsMaxElementErrorMessage; } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/validationES2.cpp b/chromium/third_party/angle/src/libANGLE/validationES2.cpp index 30c6c74173e..c92ddad83e7 100644 --- a/chromium/third_party/angle/src/libANGLE/validationES2.cpp +++ b/chromium/third_party/angle/src/libANGLE/validationES2.cpp @@ -21,6 +21,7 @@ #include "libANGLE/Uniform.h" #include "common/mathutil.h" +#include "common/string_utils.h" #include "common/utilities.h" namespace gl @@ -60,11 +61,245 @@ bool IsPartialBlit(gl::Context *context, return false; } +template <typename T> +bool ValidatePathInstances(gl::Context *context, + GLsizei numPaths, + const void *paths, + GLuint pathBase) +{ + const auto *array = static_cast<const T *>(paths); + + for (GLsizei i = 0; i < numPaths; ++i) + { + const GLuint pathName = array[i] + pathBase; + if (context->hasPath(pathName) && !context->hasPathData(pathName)) + { + context->handleError(gl::Error(GL_INVALID_OPERATION, "No such path object.")); + return false; + } + } + return true; +} + +bool ValidateInstancedPathParameters(gl::Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError( + gl::Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available.")); + return false; + } + + if (paths == nullptr) + { + context->handleError(gl::Error(GL_INVALID_VALUE, "No path name array.")); + return false; + } + + if (numPaths < 0) + { + context->handleError(gl::Error(GL_INVALID_VALUE, "Invalid (negative) numPaths.")); + return false; + } + + if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths)) + { + context->handleError(gl::Error(GL_INVALID_OPERATION, "Overflow in numPaths.")); + return false; + } + + std::uint32_t pathNameTypeSize = 0; + std::uint32_t componentCount = 0; + + switch (pathNameType) + { + case GL_UNSIGNED_BYTE: + pathNameTypeSize = sizeof(GLubyte); + if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_BYTE: + pathNameTypeSize = sizeof(GLbyte); + if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_UNSIGNED_SHORT: + pathNameTypeSize = sizeof(GLushort); + if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_SHORT: + pathNameTypeSize = sizeof(GLshort); + if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_UNSIGNED_INT: + pathNameTypeSize = sizeof(GLuint); + if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_INT: + pathNameTypeSize = sizeof(GLint); + if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase)) + return false; + break; + + default: + context->handleError(gl::Error(GL_INVALID_ENUM, "Invalid path name type.")); + return false; + } + + switch (transformType) + { + case GL_NONE: + componentCount = 0; + break; + case GL_TRANSLATE_X_CHROMIUM: + case GL_TRANSLATE_Y_CHROMIUM: + componentCount = 1; + break; + case GL_TRANSLATE_2D_CHROMIUM: + componentCount = 2; + break; + case GL_TRANSLATE_3D_CHROMIUM: + componentCount = 3; + break; + case GL_AFFINE_2D_CHROMIUM: + case GL_TRANSPOSE_AFFINE_2D_CHROMIUM: + componentCount = 6; + break; + case GL_AFFINE_3D_CHROMIUM: + case GL_TRANSPOSE_AFFINE_3D_CHROMIUM: + componentCount = 12; + break; + default: + context->handleError(gl::Error(GL_INVALID_ENUM, "Invalid transformation.")); + return false; + } + if (componentCount != 0 && transformValues == nullptr) + { + context->handleError(gl::Error(GL_INVALID_VALUE, "No transform array given.")); + return false; + } + + angle::CheckedNumeric<std::uint32_t> checkedSize(0); + checkedSize += (numPaths * pathNameTypeSize); + checkedSize += (numPaths * sizeof(GLfloat) * componentCount); + if (!checkedSize.IsValid()) + { + context->handleError(gl::Error(GL_INVALID_OPERATION, "Overflow in num paths.")); + return false; + } + + return true; +} + +bool IsValidCopyTextureFormat(Context *context, GLenum internalFormat) +{ + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat); + switch (internalFormatInfo.format) + { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGB: + case GL_RGBA: + return true; + + case GL_RED: + return context->getClientMajorVersion() >= 3 || context->getExtensions().textureRG; + + case GL_BGRA_EXT: + return context->getExtensions().textureFormatBGRA8888; + + default: + return false; + } +} + +bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type) +{ + switch (internalFormat) + { + case GL_RGB: + case GL_RGBA: + break; + + case GL_BGRA_EXT: + return context->getExtensions().textureFormatBGRA8888; + + default: + return false; + } + + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + + default: + return false; + } + + return true; +} + +bool IsValidCopyTextureDestinationTarget(Context *context, GLenum target) +{ + switch (target) + { + case GL_TEXTURE_2D: + return true; + + // TODO(geofflang): accept GL_TEXTURE_RECTANGLE_ARB if the texture_rectangle extension is + // supported + + default: + return false; + } +} + +bool IsValidCopyTextureSourceTarget(Context *context, GLenum target) +{ + if (IsValidCopyTextureDestinationTarget(context, target)) + { + return true; + } + + // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is + // supported + + return false; +} + } // anonymous namespace -bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, - GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const GLvoid *pixels) +bool ValidateES2TexImageParameters(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const GLvoid *pixels) { if (!ValidTexture2DDestinationTarget(context, target)) { @@ -135,7 +370,8 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, { if (format != GL_NONE) { - if (gl::GetSizedInternalFormat(format, type) != texture->getInternalFormat(target, level)) + if (gl::GetSizedInternalFormat(format, type) != + texture->getFormat(target, level).asSized()) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -168,7 +404,7 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, if (isCompressed) { GLenum actualInternalFormat = - isSubImage ? texture->getInternalFormat(target, level) : internalformat; + isSubImage ? texture->getFormat(target, level).asSized() : internalformat; switch (actualInternalFormat) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: @@ -468,6 +704,12 @@ bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, } } + if (!ValidImageDataSize(context, target, width, height, 1, internalformat, type, pixels, + imageSize)) + { + return false; + } + return true; } @@ -484,29 +726,28 @@ bool ValidateES2CopyTexImageParameters(ValidationContext *context, GLsizei height, GLint border) { - GLenum textureInternalFormat = GL_NONE; - if (!ValidTexture2DDestinationTarget(context, target)) { context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target")); return false; } + Format textureFormat = Format::Invalid(); if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, - xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat)) + xoffset, yoffset, 0, x, y, width, height, border, + &textureFormat)) { return false; } const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); - GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat(); - const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat); - GLenum textureFormat = internalFormatInfo.format; + GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getFormat().asSized(); + const auto &formatInfo = *textureFormat.info; // [OpenGL ES 2.0.24] table 3.9 if (isSubImage) { - switch (textureFormat) + switch (formatInfo.format) { case GL_ALPHA: if (colorbufferFormat != GL_ALPHA8_EXT && @@ -604,8 +845,7 @@ bool ValidateES2CopyTexImageParameters(ValidationContext *context, return false; } - if (internalFormatInfo.type == GL_FLOAT && - !context->getExtensions().textureFloat) + if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -965,52 +1205,6 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le return true; } -// check for combinations of format and type that are valid for ReadPixels -bool ValidES2ReadFormatType(ValidationContext *context, GLenum format, GLenum type) -{ - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - return false; - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - break; - default: - return false; - } - break; - case GL_RG_EXT: - case GL_RED_EXT: - if (!context->getExtensions().textureRG) - { - return false; - } - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - return false; - } - break; - - default: - return false; - } - return true; -} - bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments, const GLenum *attachments) { @@ -1454,6 +1648,30 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, context->handleError(Error(GL_INVALID_ENUM, "Invalid identifier.")); return false; } +} + +static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label) +{ + size_t labelLength = 0; + + if (length < 0) + { + if (label != nullptr) + { + labelLength = strlen(label); + } + } + else + { + labelLength = static_cast<size_t>(length); + } + + if (labelLength > context->getExtensions().maxLabelLength) + { + context->handleError( + Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH.")); + return false; + } return true; } @@ -1475,11 +1693,8 @@ bool ValidateObjectLabelKHR(Context *context, return false; } - size_t labelLength = (length < 0) ? strlen(label) : length; - if (labelLength > context->getExtensions().maxLabelLength) + if (!ValidateLabelLength(context, length, label)) { - context->handleError( - Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH.")); return false; } @@ -1510,8 +1725,7 @@ bool ValidateGetObjectLabelKHR(Context *context, return false; } - // Can no-op if bufSize is zero. - return bufSize > 0; + return true; } static bool ValidateObjectPtrName(Context *context, const void *ptr) @@ -1541,11 +1755,8 @@ bool ValidateObjectPtrLabelKHR(Context *context, return false; } - size_t labelLength = (length < 0) ? strlen(label) : length; - if (labelLength > context->getExtensions().maxLabelLength) + if (!ValidateLabelLength(context, length, label)) { - context->handleError( - Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH.")); return false; } @@ -1575,8 +1786,7 @@ bool ValidateGetObjectPtrLabelKHR(Context *context, return false; } - // Can no-op if bufSize is zero. - return bufSize > 0; + return true; } bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params) @@ -1671,7 +1881,8 @@ bool ValidateBlitFramebufferANGLE(Context *context, } // Return an error if the destination formats do not match - if (attachment->getInternalFormat() != readColorAttachment->getInternalFormat()) + if (!Format::SameSized(attachment->getFormat(), + readColorAttachment->getFormat())) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1766,15 +1977,46 @@ bool ValidateTexImage2D(Context *context, GLenum type, const GLvoid *pixels) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, target, level, internalformat, false, false, + 0, 0, width, height, border, format, type, -1, pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0, + 0, 0, width, height, 1, border, format, type, -1, + pixels); +} + +bool ValidateTexImage2DRobust(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLvoid *pixels) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (context->getClientMajorVersion() < 3) { return ValidateES2TexImageParameters(context, target, level, internalformat, false, false, - 0, 0, width, height, border, format, type, pixels); + 0, 0, width, height, border, format, type, bufSize, + pixels); } - ASSERT(context->getClientVersion() >= 3); + ASSERT(context->getClientMajorVersion() >= 3); return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0, - 0, 0, width, height, 1, border, format, type, pixels); + 0, 0, width, height, 1, border, format, type, bufSize, + pixels); } bool ValidateTexSubImage2D(Context *context, @@ -1789,15 +2031,16 @@ bool ValidateTexSubImage2D(Context *context, const GLvoid *pixels) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset, - yoffset, width, height, 0, format, type, pixels); + yoffset, width, height, 0, format, type, -1, pixels); } - ASSERT(context->getClientVersion() >= 3); + ASSERT(context->getClientMajorVersion() >= 3); return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset, - yoffset, 0, width, height, 1, 0, format, type, pixels); + yoffset, 0, width, height, 1, 0, format, type, -1, + pixels); } bool ValidateCompressedTexImage2D(Context *context, @@ -1810,19 +2053,19 @@ bool ValidateCompressedTexImage2D(Context *context, GLsizei imageSize, const GLvoid *data) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0, - 0, width, height, border, GL_NONE, GL_NONE, data)) + 0, width, height, border, GL_NONE, GL_NONE, -1, data)) { return false; } } else { - ASSERT(context->getClientVersion() >= 3); + ASSERT(context->getClientMajorVersion() >= 3); if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0, - 0, 0, width, height, 1, border, GL_NONE, GL_NONE, + 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1, data)) { return false; @@ -1858,19 +2101,19 @@ bool ValidateCompressedTexSubImage2D(Context *context, GLsizei imageSize, const GLvoid *data) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset, - yoffset, width, height, 0, GL_NONE, GL_NONE, data)) + yoffset, width, height, 0, GL_NONE, GL_NONE, -1, data)) { return false; } } else { - ASSERT(context->getClientVersion() >= 3); + ASSERT(context->getClientMajorVersion() >= 3); if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset, - yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, + yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, -1, data)) { return false; @@ -1994,6 +2237,13 @@ bool ValidateBindTexture(Context *context, GLenum target, GLuint texture) return false; } + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isTextureGenerated(texture)) + { + context->handleError(Error(GL_INVALID_OPERATION, "Texture was not generated")); + return false; + } + switch (target) { case GL_TEXTURE_2D: @@ -2002,7 +2252,7 @@ bool ValidateBindTexture(Context *context, GLenum target, GLuint texture) case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_ENUM, "GLES 3.0 disabled")); return false; @@ -2552,4 +2802,666 @@ bool ValidateIsPath(Context *context) return true; } +bool ValidateCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + context->handleError(Error(GL_INVALID_ENUM, "Invalid cover mode.")); + return false; + } + + return true; +} + +bool ValidateCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + context->handleError(Error(GL_INVALID_ENUM, "Invalid cover mode.")); + return false; + } + + return true; +} + +bool ValidateStencilFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (fillMode) + { + case GL_COUNT_UP_CHROMIUM: + case GL_COUNT_DOWN_CHROMIUM: + break; + default: + context->handleError(Error(GL_INVALID_ENUM, "Invalid fill mode.")); + return false; + } + if (!isPow2(mask + 1)) + { + context->handleError(Error(GL_INVALID_VALUE, "Invalid stencil bit mask.")); + return false; + } + return true; +} + +bool ValidateStencilStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + // no more validation here. + + return true; +} + +bool ValidateStencilThenCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + context->handleError(Error(GL_INVALID_ENUM, "Invalid cover mode.")); + return false; + } + + switch (fillMode) + { + case GL_COUNT_UP_CHROMIUM: + case GL_COUNT_DOWN_CHROMIUM: + break; + default: + context->handleError(Error(GL_INVALID_ENUM, "Invalid fill mode.")); + return false; + } + if (!isPow2(mask + 1)) + { + context->handleError(Error(GL_INVALID_VALUE, "Invalid stencil bit mask.")); + return false; + } + + return true; +} + +bool ValidateStencilThenCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + context->handleError(Error(GL_INVALID_ENUM, "Invalid cover mode.")); + return false; + } + + return true; +} + +bool ValidateBindFragmentInputLocation(Context *context, + GLuint program, + GLint location, + const GLchar *name) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError( + Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available.")); + return false; + } + + const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4; + if (location >= MaxLocation) + { + context->handleError(Error(GL_INVALID_VALUE, "Location exceeds max varying.")); + return false; + } + + const auto *programObject = context->getProgram(program); + if (!programObject) + { + context->handleError(Error(GL_INVALID_OPERATION, "No such program.")); + return false; + } + + if (!name) + { + context->handleError(Error(GL_INVALID_VALUE, "No name given.")); + return false; + } + + if (angle::BeginsWith(name, "gl_")) + { + context->handleError(Error(GL_INVALID_OPERATION, "Cannot bind a built-in variable.")); + return false; + } + + return true; +} + +bool ValidateProgramPathFragmentInputGen(Context *context, + GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError( + Error(GL_INVALID_OPERATION, "GL_CHROMIUM_path_rendering is not available.")); + return false; + } + + const auto *programObject = context->getProgram(program); + if (!programObject || programObject->isFlaggedForDeletion()) + { + context->handleError(Error(GL_INVALID_OPERATION, "No such program.")); + return false; + } + + if (!programObject->isLinked()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Program is not linked.")); + return false; + } + + switch (genMode) + { + case GL_NONE: + if (components != 0) + { + context->handleError(Error(GL_INVALID_VALUE, "Invalid components.")); + return false; + } + break; + + case GL_OBJECT_LINEAR_CHROMIUM: + case GL_EYE_LINEAR_CHROMIUM: + case GL_CONSTANT_CHROMIUM: + if (components < 1 || components > 4) + { + context->handleError(Error(GL_INVALID_VALUE, "Invalid components.")); + return false; + } + if (!coeffs) + { + context->handleError(Error(GL_INVALID_VALUE, "No coefficients array given.")); + return false; + } + break; + + default: + context->handleError(Error(GL_INVALID_ENUM, "Invalid gen mode.")); + return false; + } + + // If the location is -1 then the command is silently ignored + // and no further validation is needed. + if (location == -1) + return true; + + const auto &binding = programObject->getFragmentInputBindingInfo(location); + + if (!binding.valid) + { + context->handleError(Error(GL_INVALID_OPERATION, "No such binding.")); + return false; + } + + if (binding.type != GL_NONE) + { + GLint expectedComponents = 0; + switch (binding.type) + { + case GL_FLOAT: + expectedComponents = 1; + break; + case GL_FLOAT_VEC2: + expectedComponents = 2; + break; + case GL_FLOAT_VEC3: + expectedComponents = 3; + break; + case GL_FLOAT_VEC4: + expectedComponents = 4; + break; + default: + context->handleError(Error(GL_INVALID_OPERATION, + "Fragment input type is not a floating point scalar or vector.")); + return false; + } + if (expectedComponents != components && genMode != GL_NONE) + { + context->handleError(Error(GL_INVALID_OPERATION, "Unexpected number of components")); + return false; + } + } + return true; +} + +bool ValidateCopyTextureCHROMIUM(Context *context, + GLuint sourceId, + GLuint destId, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + if (!context->getExtensions().copyTexture) + { + context->handleError( + Error(GL_INVALID_OPERATION, "GL_CHROMIUM_copy_texture extension not available.")); + return false; + } + + const gl::Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->handleError( + Error(GL_INVALID_VALUE, "Source texture is not a valid texture object.")); + return false; + } + + if (!IsValidCopyTextureSourceTarget(context, source->getTarget())) + { + context->handleError(Error(GL_INVALID_VALUE, "Source texture a valid texture type.")); + return false; + } + + GLenum sourceTarget = source->getTarget(); + ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP); + if (source->getWidth(sourceTarget, 0) == 0 || source->getHeight(sourceTarget, 0) == 0) + { + context->handleError( + Error(GL_INVALID_VALUE, "Level 0 of the source texture must be defined.")); + return false; + } + + const gl::Format &sourceFormat = source->getFormat(sourceTarget, 0); + if (!IsValidCopyTextureFormat(context, sourceFormat.format)) + { + context->handleError( + Error(GL_INVALID_OPERATION, "Source texture internal format is invalid.")); + return false; + } + + const gl::Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->handleError( + Error(GL_INVALID_VALUE, "Destination texture is not a valid texture object.")); + return false; + } + + if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget())) + { + context->handleError(Error(GL_INVALID_VALUE, "Destination texture a valid texture type.")); + return false; + } + + if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType)) + { + context->handleError( + Error(GL_INVALID_OPERATION, + "Destination internal format and type combination is not valid.")); + return false; + } + + if (dest->getImmutableFormat()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Destination texture is immutable.")); + return false; + } + + return true; +} + +bool ValidateCopySubTextureCHROMIUM(Context *context, + GLuint sourceId, + GLuint destId, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + if (!context->getExtensions().copyTexture) + { + context->handleError( + Error(GL_INVALID_OPERATION, "GL_CHROMIUM_copy_texture extension not available.")); + return false; + } + + const gl::Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->handleError( + Error(GL_INVALID_VALUE, "Source texture is not a valid texture object.")); + return false; + } + + if (!IsValidCopyTextureSourceTarget(context, source->getTarget())) + { + context->handleError(Error(GL_INVALID_VALUE, "Source texture a valid texture type.")); + return false; + } + + GLenum sourceTarget = source->getTarget(); + ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP); + if (source->getWidth(sourceTarget, 0) == 0 || source->getHeight(sourceTarget, 0) == 0) + { + context->handleError( + Error(GL_INVALID_VALUE, "Level 0 of the source texture must be defined.")); + return false; + } + + if (x < 0 || y < 0) + { + context->handleError(Error(GL_INVALID_VALUE, "x and y cannot be negative.")); + return false; + } + + if (width < 0 || height < 0) + { + context->handleError(Error(GL_INVALID_VALUE, "width and height cannot be negative.")); + return false; + } + + if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, 0) || + static_cast<size_t>(y + height) > source->getHeight(sourceTarget, 0)) + { + context->handleError( + Error(GL_INVALID_VALUE, "Source texture not large enough to copy from.")); + return false; + } + + const gl::Format &sourceFormat = source->getFormat(sourceTarget, 0); + if (!IsValidCopyTextureFormat(context, sourceFormat.format)) + { + context->handleError( + Error(GL_INVALID_OPERATION, "Source texture internal format is invalid.")); + return false; + } + + const gl::Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->handleError( + Error(GL_INVALID_VALUE, "Destination texture is not a valid texture object.")); + return false; + } + + if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget())) + { + context->handleError(Error(GL_INVALID_VALUE, "Destination texture a valid texture type.")); + return false; + } + + GLenum destTarget = dest->getTarget(); + ASSERT(destTarget != GL_TEXTURE_CUBE_MAP); + if (dest->getWidth(sourceTarget, 0) == 0 || dest->getHeight(sourceTarget, 0) == 0) + { + context->handleError( + Error(GL_INVALID_VALUE, "Level 0 of the destination texture must be defined.")); + return false; + } + + const gl::Format &destFormat = dest->getFormat(destTarget, 0); + if (!IsValidCopyTextureDestinationFormatType(context, destFormat.format, destFormat.type)) + { + context->handleError( + Error(GL_INVALID_OPERATION, + "Destination internal format and type combination is not valid.")); + return false; + } + + if (xoffset < 0 || yoffset < 0) + { + context->handleError(Error(GL_INVALID_VALUE, "xoffset and yoffset cannot be negative.")); + return false; + } + + if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, 0) || + static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, 0)) + { + context->handleError( + Error(GL_INVALID_VALUE, "Destination texture not large enough to copy to.")); + return false; + } + + return true; +} + +bool ValidateCreateShader(Context *context, GLenum type) +{ + switch (type) + { + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + break; + case GL_COMPUTE_SHADER: + if (context->getGLVersion().isES31()) + { + break; + } + default: + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + return true; +} + +bool ValidateBufferData(ValidationContext *context, + GLenum target, + GLsizeiptr size, + const GLvoid *data, + GLenum usage) +{ + if (size < 0) + { + context->handleError(Error(GL_INVALID_VALUE)); + return false; + } + + switch (usage) + { + case GL_STREAM_DRAW: + case GL_STATIC_DRAW: + case GL_DYNAMIC_DRAW: + break; + + case GL_STREAM_READ: + case GL_STREAM_COPY: + case GL_STATIC_READ: + case GL_STATIC_COPY: + case GL_DYNAMIC_READ: + case GL_DYNAMIC_COPY: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + break; + + default: + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + if (!ValidBufferTarget(context, target)) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (!buffer) + { + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + + return true; +} + +bool ValidateBufferSubData(ValidationContext *context, + GLenum target, + GLintptr offset, + GLsizeiptr size, + const GLvoid *data) +{ + if (size < 0 || offset < 0) + { + context->handleError(Error(GL_INVALID_VALUE)); + return false; + } + + if (!ValidBufferTarget(context, target)) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (!buffer) + { + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + + if (buffer->isMapped()) + { + context->handleError(Error(GL_INVALID_OPERATION)); + return false; + } + + // Check for possible overflow of size + offset + angle::CheckedNumeric<size_t> checkedSize(size); + checkedSize += offset; + if (!checkedSize.IsValid()) + { + context->handleError(Error(GL_OUT_OF_MEMORY)); + return false; + } + + if (size + offset > buffer->getSize()) + { + context->handleError(Error(GL_INVALID_VALUE)); + return false; + } + + return true; +} + +bool ValidateEnableExtensionANGLE(ValidationContext *context, const GLchar *name) +{ + if (!context->getExtensions().webglCompatibility) + { + context->handleError( + Error(GL_INVALID_OPERATION, "GL_ANGLE_webgl_compatibility is not available.")); + return false; + } + + const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap(); + auto extension = extensionInfos.find(name); + if (extension == extensionInfos.end() || !extension->second.Enableable) + { + context->handleError(Error(GL_INVALID_OPERATION, "Extension %s is not enableable.", name)); + return false; + } + + return true; +} + } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/validationES2.h b/chromium/third_party/angle/src/libANGLE/validationES2.h index 5433e8d6589..8f0dc1a4d96 100644 --- a/chromium/third_party/angle/src/libANGLE/validationES2.h +++ b/chromium/third_party/angle/src/libANGLE/validationES2.h @@ -18,9 +18,21 @@ class Context; class ValidationContext; class Texture; -bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, - GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const GLvoid *pixels); +bool ValidateES2TexImageParameters(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const GLvoid *pixels); bool ValidateES2CopyTexImageParameters(ValidationContext *context, GLenum target, @@ -38,8 +50,6 @@ bool ValidateES2CopyTexImageParameters(ValidationContext *context, bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -bool ValidES2ReadFormatType(ValidationContext *context, GLenum format, GLenum type); - bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments, const GLenum *attachments); @@ -139,6 +149,17 @@ bool ValidateTexImage2D(Context *context, GLenum format, GLenum type, const GLvoid *pixels); +bool ValidateTexImage2DRobust(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const GLvoid *pixels); bool ValidateTexSubImage2D(Context *context, GLenum target, GLint level, @@ -219,6 +240,105 @@ bool ValidateStencilThenCoverStrokePath(Context *context, GLuint mask, GLenum coverMode); bool ValidateIsPath(Context *context); +bool ValidateCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBAse, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilThenCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilThenCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateBindFragmentInputLocation(Context *context, + GLuint program, + GLint location, + const GLchar *name); +bool ValidateProgramPathFragmentInputGen(Context *context, + GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + +bool ValidateCopyTextureCHROMIUM(Context *context, + GLuint sourceId, + GLuint destId, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +bool ValidateCopySubTextureCHROMIUM(Context *context, + GLuint sourceId, + GLuint destId, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +bool ValidateCreateShader(Context *context, GLenum type); +bool ValidateBufferData(ValidationContext *context, + GLenum target, + GLsizeiptr size, + const GLvoid *data, + GLenum usage); +bool ValidateBufferSubData(ValidationContext *context, + GLenum target, + GLintptr offset, + GLsizeiptr size, + const GLvoid *data); + +bool ValidateEnableExtensionANGLE(ValidationContext *context, const GLchar *name); } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/validationES3.cpp b/chromium/third_party/angle/src/libANGLE/validationES3.cpp index 21c20f15e6b..b635c50bf19 100644 --- a/chromium/third_party/angle/src/libANGLE/validationES3.cpp +++ b/chromium/third_party/angle/src/libANGLE/validationES3.cpp @@ -53,6 +53,7 @@ ES3FormatCombinationSet BuildES3FormatSet() // Format combinations from ES 3.0.1 spec, table 3.2 + // clang-format off // | Internal format | Format | Type | // | | | | InsertES3FormatCombo(&set, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE ); @@ -164,6 +165,8 @@ ES3FormatCombinationSet BuildES3FormatSet() InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_FLOAT ); // From GL_OES_texture_half_float + InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_HALF_FLOAT_OES ); + InsertES3FormatCombo(&set, GL_RGB, GL_RGB, GL_HALF_FLOAT_OES ); InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ); InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES ); InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT ); @@ -197,8 +200,11 @@ ES3FormatCombinationSet BuildES3FormatSet() InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT); InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ); - // From GL_ANGLE_depth_texture + // From GL_ANGLE_depth_texture and OES_depth_texture InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES ); + InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT ); + InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ); + // clang-format on // From GL_EXT_texture_norm16 InsertES3FormatCombo(&set, GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT); @@ -220,7 +226,7 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter // error instead of a GL_INVALID_ENUM error. As this validation function is only called in // the validation codepaths for glTexImage2D/3D, we record a GL_INVALID_VALUE error. const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + if (!formatInfo.textureSupport(context->getClientMajorVersion(), context->getExtensions())) { context->handleError(Error(GL_INVALID_VALUE)); return false; @@ -236,7 +242,8 @@ static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum inter if (i->format == format || i->type == type) { const gl::InternalFormat &info = gl::GetInternalFormatInfo(i->internalFormat); - bool supported = info.textureSupport(context->getClientVersion(), context->getExtensions()); + bool supported = + info.textureSupport(context->getClientMajorVersion(), context->getExtensions()); if (supported && i->type == type) { typeSupported = true; @@ -290,6 +297,7 @@ bool ValidateES3TexImageParametersBase(Context *context, GLint border, GLenum format, GLenum type, + GLsizei imageSize, const GLvoid *pixels) { // Validate image size @@ -386,7 +394,8 @@ bool ValidateES3TexImageParametersBase(Context *context, } // Validate texture formats - GLenum actualInternalFormat = isSubImage ? texture->getInternalFormat(target, level) : internalformat; + GLenum actualInternalFormat = + isSubImage ? texture->getFormat(target, level).asSized() : internalformat; const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(actualInternalFormat); if (isCompressed) { @@ -403,7 +412,8 @@ bool ValidateES3TexImageParametersBase(Context *context, return false; } - if (!actualFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + if (!actualFormatInfo.textureSupport(context->getClientMajorVersion(), + context->getExtensions())) { context->handleError(Error(GL_INVALID_ENUM)); return false; @@ -466,70 +476,27 @@ bool ValidateES3TexImageParametersBase(Context *context, } } + if (!ValidImageDataSize(context, target, width, height, 1, actualInternalFormat, type, pixels, + imageSize)) + { + return false; + } + // Check for pixel unpack buffer related API errors gl::Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER); - if (pixelUnpackBuffer != NULL) + if (pixelUnpackBuffer != nullptr) { - // ...the data would be unpacked from the buffer object such that the memory reads required - // would exceed the data store size. - GLenum sizedFormat = GetSizedInternalFormat(actualInternalFormat, type); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat); - const gl::Extents size(width, height, depth); - const auto &unpack = context->getGLState().getUnpackState(); - - auto copyBytesOrErr = formatInfo.computeUnpackSize(type, size, unpack); - if (copyBytesOrErr.isError()) - { - context->handleError(copyBytesOrErr.getError()); - return false; - } - CheckedNumeric<size_t> checkedCopyBytes(copyBytesOrErr.getResult()); - CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels)); - checkedCopyBytes += checkedOffset; - - auto rowPitchOrErr = - formatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength); - if (rowPitchOrErr.isError()) - { - context->handleError(rowPitchOrErr.getError()); - return false; - } - auto depthPitchOrErr = formatInfo.computeDepthPitch(type, width, height, unpack.alignment, - unpack.rowLength, unpack.imageHeight); - if (depthPitchOrErr.isError()) - { - context->handleError(depthPitchOrErr.getError()); - return false; - } - - bool targetIs3D = target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY; - auto skipBytesOrErr = formatInfo.computeSkipBytes( - rowPitchOrErr.getResult(), depthPitchOrErr.getResult(), unpack.skipImages, - unpack.skipRows, unpack.skipPixels, targetIs3D); - if (skipBytesOrErr.isError()) - { - context->handleError(skipBytesOrErr.getError()); - return false; - } - checkedCopyBytes += skipBytesOrErr.getResult(); - - if (!checkedCopyBytes.IsValid() || - (checkedCopyBytes.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize()))) - { - // Overflow past the end of the buffer - context->handleError(Error(GL_INVALID_OPERATION)); - return false; - } - // ...data is not evenly divisible into the number of bytes needed to store in memory a datum // indicated by type. if (!isCompressed) { + size_t offset = reinterpret_cast<size_t>(pixels); size_t dataBytesPerPixel = static_cast<size_t>(gl::GetTypeInfo(type).bytes); - if ((checkedOffset.ValueOrDie() % dataBytesPerPixel) != 0) + if ((offset % dataBytesPerPixel) != 0) { - context->handleError(Error(GL_INVALID_OPERATION)); + context->handleError( + Error(GL_INVALID_OPERATION, "Reads would overflow the pixel unpack buffer.")); return false; } } @@ -537,7 +504,7 @@ bool ValidateES3TexImageParametersBase(Context *context, // ...the buffer object's data store is currently mapped. if (pixelUnpackBuffer->isMapped()) { - context->handleError(Error(GL_INVALID_OPERATION)); + context->handleError(Error(GL_INVALID_OPERATION, "Pixel unpack buffer is mapped.")); return false; } } @@ -560,6 +527,7 @@ bool ValidateES3TexImage2DParameters(Context *context, GLint border, GLenum format, GLenum type, + GLsizei imageSize, const GLvoid *pixels) { if (!ValidTexture2DDestinationTarget(context, target)) @@ -570,7 +538,7 @@ bool ValidateES3TexImage2DParameters(Context *context, return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, isSubImage, xoffset, yoffset, zoffset, width, height, - depth, border, format, type, pixels); + depth, border, format, type, imageSize, pixels); } bool ValidateES3TexImage3DParameters(Context *context, @@ -598,7 +566,7 @@ bool ValidateES3TexImage3DParameters(Context *context, return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, isSubImage, xoffset, yoffset, zoffset, width, height, - depth, border, format, type, pixels); + depth, border, format, type, -1, pixels); } struct EffectiveInternalFormatInfo @@ -747,6 +715,7 @@ static CopyConversionSet BuildValidES3CopyTexImageCombinations() set.insert(CopyConversion(GL_RG, GL_BGRA_EXT)); set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT)); set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT)); + set.insert(CopyConversion(GL_BGRA_EXT, GL_BGRA_EXT)); set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER)); set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER)); @@ -767,36 +736,42 @@ static bool EqualOrFirstZero(GLuint first, GLuint second) return first == 0 || first == second; } -static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle) +static bool IsValidES3CopyTexImageCombination(const Format &textureFormat, + const Format &framebufferFormat, + GLuint readBufferHandle) { - const InternalFormat &textureInternalFormatInfo = GetInternalFormatInfo(textureInternalFormat); - const InternalFormat &framebufferInternalFormatInfo = GetInternalFormatInfo(frameBufferInternalFormat); + const auto &textureFormatInfo = *textureFormat.info; + const auto &framebufferFormatInfo = *framebufferFormat.info; static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations(); - if (conversionSet.find(CopyConversion(textureInternalFormatInfo.format, framebufferInternalFormatInfo.format)) != conversionSet.end()) + if (conversionSet.find(CopyConversion(textureFormatInfo.format, + framebufferFormatInfo.format)) != conversionSet.end()) { // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats // must both be signed, unsigned, or fixed point and both source and destinations // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed // conversion between fixed and floating point. - if ((textureInternalFormatInfo.colorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.colorEncoding == GL_SRGB)) + if ((textureFormatInfo.colorEncoding == GL_SRGB) != + (framebufferFormatInfo.colorEncoding == GL_SRGB)) { return false; } - if (((textureInternalFormatInfo.componentType == GL_INT) != (framebufferInternalFormatInfo.componentType == GL_INT )) || - ((textureInternalFormatInfo.componentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.componentType == GL_UNSIGNED_INT))) + if (((textureFormatInfo.componentType == GL_INT) != + (framebufferFormatInfo.componentType == GL_INT)) || + ((textureFormatInfo.componentType == GL_UNSIGNED_INT) != + (framebufferFormatInfo.componentType == GL_UNSIGNED_INT))) { return false; } - if ((textureInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || - textureInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED || - textureInternalFormatInfo.componentType == GL_FLOAT) && - !(framebufferInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || - framebufferInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED || - framebufferInternalFormatInfo.componentType == GL_FLOAT)) + if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || + textureFormatInfo.componentType == GL_SIGNED_NORMALIZED || + textureFormatInfo.componentType == GL_FLOAT) && + !(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || + framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED || + framebufferFormatInfo.componentType == GL_FLOAT)) { return false; } @@ -818,15 +793,16 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen if (readBufferHandle != 0) { // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer - if (framebufferInternalFormatInfo.pixelBytes > 0) + if (framebufferFormat.sized) { - sourceEffectiveFormat = &framebufferInternalFormatInfo; + sourceEffectiveFormat = &framebufferFormatInfo; } else { // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format // texture. We can use the same table we use when creating textures to get its effective sized format. - GLenum sizedInternalFormat = GetSizedInternalFormat(framebufferInternalFormatInfo.format, framebufferInternalFormatInfo.type); + GLenum sizedInternalFormat = GetSizedInternalFormat(framebufferFormatInfo.format, + framebufferFormatInfo.type); sourceEffectiveFormat = &GetInternalFormatInfo(sizedInternalFormat); } } @@ -834,10 +810,11 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen { // The effective internal format must be derived from the source framebuffer's channel sizes. // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17) - if (framebufferInternalFormatInfo.colorEncoding == GL_LINEAR) + if (framebufferFormatInfo.colorEncoding == GL_LINEAR) { GLenum effectiveFormat; - if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat)) + if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo, + &effectiveFormat)) { sourceEffectiveFormat = &GetInternalFormatInfo(effectiveFormat); } @@ -846,14 +823,15 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen return false; } } - else if (framebufferInternalFormatInfo.colorEncoding == GL_SRGB) + else if (framebufferFormatInfo.colorEncoding == GL_SRGB) { // SRGB buffers can only be copied to sized format destinations according to table 3.18 - if ((textureInternalFormatInfo.pixelBytes > 0) && - (framebufferInternalFormatInfo.redBits >= 1 && framebufferInternalFormatInfo.redBits <= 8) && - (framebufferInternalFormatInfo.greenBits >= 1 && framebufferInternalFormatInfo.greenBits <= 8) && - (framebufferInternalFormatInfo.blueBits >= 1 && framebufferInternalFormatInfo.blueBits <= 8) && - (framebufferInternalFormatInfo.alphaBits >= 1 && framebufferInternalFormatInfo.alphaBits <= 8)) + if (textureFormat.sized && + (framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) && + (framebufferFormatInfo.greenBits >= 1 && + framebufferFormatInfo.greenBits <= 8) && + (framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) && + (framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8)) { sourceEffectiveFormat = &GetInternalFormatInfo(GL_SRGB8_ALPHA8); } @@ -869,25 +847,20 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen } } - if (textureInternalFormatInfo.pixelBytes > 0) + if (textureFormat.sized) { // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination // format is sized, component sizes of the source and destination formats must exactly // match if the destination format exists. - if (!EqualOrFirstZero(textureInternalFormatInfo.redBits, - sourceEffectiveFormat->redBits) || - !EqualOrFirstZero(textureInternalFormatInfo.greenBits, - sourceEffectiveFormat->greenBits) || - !EqualOrFirstZero(textureInternalFormatInfo.blueBits, - sourceEffectiveFormat->blueBits) || - !EqualOrFirstZero(textureInternalFormatInfo.alphaBits, - sourceEffectiveFormat->alphaBits)) + if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) || + !EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) || + !EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) || + !EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits)) { return false; } } - return true; // A conversion function exists, and no rule in the specification has precluded conversion // between these formats. } @@ -909,13 +882,14 @@ bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, GLsizei height, GLint border) { - GLenum textureInternalFormat; + Format textureFormat = Format::Invalid(); if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, - xoffset, yoffset, zoffset, x, y, width, height, - border, &textureInternalFormat)) + xoffset, yoffset, zoffset, x, y, width, height, border, + &textureFormat)) { return false; } + ASSERT(textureFormat.valid() || !isSubImage); const auto &state = context->getGLState(); gl::Framebuffer *framebuffer = state.getReadFramebuffer(); @@ -933,12 +907,11 @@ bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, return false; } - const gl::FramebufferAttachment *source = framebuffer->getReadColorbuffer(); - GLenum colorbufferInternalFormat = source->getInternalFormat(); + const FramebufferAttachment *source = framebuffer->getReadColorbuffer(); if (isSubImage) { - if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, + if (!IsValidES3CopyTexImageCombination(textureFormat, source->getFormat(), readFramebufferID)) { context->handleError(Error(GL_INVALID_OPERATION)); @@ -947,8 +920,10 @@ bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, } else { - if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat, - readFramebufferID)) + // Use format/type from the source FBO. (Might not be perfect for all cases?) + const auto framebufferFormat = source->getFormat(); + Format copyFormat(internalformat, framebufferFormat.format, framebufferFormat.type); + if (!IsValidES3CopyTexImageCombination(copyFormat, framebufferFormat, readFramebufferID)) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1109,7 +1084,7 @@ bool ValidateES3TexStorageParametersBase(Context *context, } const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); - if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + if (!formatInfo.textureSupport(context->getClientMajorVersion(), context->getExtensions())) { context->handleError(Error(GL_INVALID_ENUM)); return false; @@ -1162,7 +1137,7 @@ bool ValidateES3TexStorage3DParameters(Context *context, bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); return false; @@ -1173,7 +1148,7 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) bool ValidateEndQuery(gl::Context *context, GLenum target) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); return false; @@ -1184,7 +1159,7 @@ bool ValidateEndQuery(gl::Context *context, GLenum target) bool ValidateGetQueryiv(Context *context, GLenum target, GLenum pname, GLint *params) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); return false; @@ -1195,7 +1170,7 @@ bool ValidateGetQueryiv(Context *context, GLenum target, GLenum pname, GLint *pa bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint *params) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); return false; @@ -1207,7 +1182,7 @@ bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1269,8 +1244,8 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att return false; } - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(tex->getInternalFormat(tex->getTarget(), level)); - if (internalFormatInfo.compressed) + const auto &format = tex->getFormat(tex->getTarget(), level); + if (format.info->compressed) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1280,100 +1255,6 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att return true; } -bool ValidES3ReadFormatType(ValidationContext *context, - GLenum internalFormat, - GLenum format, - GLenum type) -{ - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - case GL_UNSIGNED_SHORT: - if (internalFormatInfo.componentType != GL_UNSIGNED_NORMALIZED && - internalFormatInfo.type != GL_UNSIGNED_SHORT) - { - return false; - } - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (internalFormat != GL_RGB10_A2) - { - return false; - } - break; - case GL_FLOAT: - if (internalFormatInfo.componentType != GL_FLOAT) - { - return false; - } - break; - default: - return false; - } - break; - case GL_RGBA_INTEGER: - switch (type) - { - case GL_INT: - if (internalFormatInfo.componentType != GL_INT) - { - return false; - } - break; - case GL_UNSIGNED_INT: - if (internalFormatInfo.componentType != GL_UNSIGNED_INT) - { - return false; - } - break; - default: - return false; - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - break; - default: - return false; - } - break; - case GL_RG_EXT: - case GL_RED_EXT: - if (!context->getExtensions().textureRG) - { - return false; - } - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - case GL_UNSIGNED_SHORT: - if (internalFormatInfo.componentType != GL_UNSIGNED_NORMALIZED && - internalFormatInfo.type != GL_UNSIGNED_SHORT) - { - return false; - } - break; - default: - return false; - } - break; - default: - return false; - } - return true; -} - bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { @@ -1406,7 +1287,7 @@ bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum targe bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments, const GLenum *attachments) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError( Error(GL_INVALID_OPERATION, "Operation only supported on ES 3.0 and above")); @@ -1434,7 +1315,7 @@ bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numA bool ValidateClearBuffer(ValidationContext *context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1459,7 +1340,7 @@ bool ValidateDrawRangeElements(Context *context, const GLvoid *indices, IndexRange *indexRange) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -1488,7 +1369,7 @@ bool ValidateDrawRangeElements(Context *context, bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1499,7 +1380,7 @@ bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLu bool ValidateReadBuffer(Context *context, GLenum src) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1559,7 +1440,7 @@ bool ValidateCompressedTexImage3D(Context *context, GLsizei imageSize, const GLvoid *data) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1618,7 +1499,7 @@ bool ValidateCompressedTexImage3D(Context *context, bool ValidateBindVertexArray(Context *context, GLuint array) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1629,7 +1510,7 @@ bool ValidateBindVertexArray(Context *context, GLuint array) bool ValidateIsVertexArray(Context *context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1644,7 +1525,7 @@ bool ValidateProgramBinary(Context *context, const void *binary, GLint length) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1660,7 +1541,7 @@ bool ValidateGetProgramBinary(Context *context, GLenum *binaryFormat, void *binary) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1671,7 +1552,7 @@ bool ValidateGetProgramBinary(Context *context, bool ValidateProgramParameteri(Context *context, GLuint program, GLenum pname, GLint value) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -1713,7 +1594,7 @@ bool ValidateBlitFramebuffer(Context *context, GLbitfield mask, GLenum filter) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1837,7 +1718,7 @@ bool ValidateClearBufferfi(ValidationContext *context, bool ValidateDrawBuffers(ValidationContext *context, GLsizei n, const GLenum *bufs) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -1857,7 +1738,7 @@ bool ValidateCopyTexSubImage3D(Context *context, GLsizei width, GLsizei height) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1879,7 +1760,7 @@ bool ValidateTexImage3D(Context *context, GLenum type, const GLvoid *pixels) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1903,7 +1784,7 @@ bool ValidateTexSubImage3D(Context *context, GLenum type, const GLvoid *pixels) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -1927,7 +1808,7 @@ bool ValidateCompressedTexSubImage3D(Context *context, GLsizei imageSize, const GLvoid *data) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -2014,7 +1895,7 @@ bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *) bool ValidateGenOrDeleteES3(Context *context, GLint n) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -2024,7 +1905,7 @@ bool ValidateGenOrDeleteES3(Context *context, GLint n) bool ValidateGenOrDeleteCountES3(Context *context, GLint count) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -2039,7 +1920,7 @@ bool ValidateGenOrDeleteCountES3(Context *context, GLint count) bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -2069,7 +1950,7 @@ bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode) bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -2102,7 +1983,7 @@ bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, G bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, GLvoid **params) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -2113,7 +1994,7 @@ bool ValidateGetBufferPointerv(Context *context, GLenum target, GLenum pname, GL bool ValidateUnmapBuffer(Context *context, GLenum target) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return false; @@ -2128,7 +2009,7 @@ bool ValidateMapBufferRange(Context *context, GLsizeiptr length, GLbitfield access) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -2142,7 +2023,7 @@ bool ValidateFlushMappedBufferRange(Context *context, GLintptr offset, GLsizeiptr length) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); return false; @@ -2151,4 +2032,78 @@ bool ValidateFlushMappedBufferRange(Context *context, return ValidateFlushMappedBufferRangeBase(context, target, offset, length); } +bool ValidateIndexedStateQuery(ValidationContext *context, GLenum pname, GLuint index) +{ + GLenum nativeType; + unsigned int numParams; + if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams)) + { + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + const Caps &caps = context->getCaps(); + switch (pname) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + if (index >= caps.maxTransformFeedbackSeparateAttributes) + { + context->handleError(Error(GL_INVALID_VALUE)); + return false; + } + break; + + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_BINDING: + if (index >= caps.maxUniformBufferBindings) + { + context->handleError(Error(GL_INVALID_VALUE)); + return false; + } + break; + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + if (index >= 3u) + { + context->handleError(Error(GL_INVALID_VALUE)); + return false; + } + break; + default: + context->handleError(Error(GL_INVALID_ENUM)); + return false; + } + + // pname is valid, but there are no parameters to return + if (numParams == 0) + { + return false; + } + + return true; +} + +bool ValidateGetIntegeri_v(ValidationContext *context, GLenum target, GLuint index, GLint *data) +{ + if (!context->getGLVersion().isES3OrGreater()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.0")); + return false; + } + return ValidateIndexedStateQuery(context, target, index); +} + +bool ValidateGetInteger64i_v(ValidationContext *context, GLenum target, GLuint index, GLint64 *data) +{ + if (!context->getGLVersion().isES3OrGreater()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.0")); + return false; + } + return ValidateIndexedStateQuery(context, target, index); +} + } // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/validationES3.h b/chromium/third_party/angle/src/libANGLE/validationES3.h index 15e6966705b..6cef7960975 100644 --- a/chromium/third_party/angle/src/libANGLE/validationES3.h +++ b/chromium/third_party/angle/src/libANGLE/validationES3.h @@ -32,6 +32,7 @@ bool ValidateES3TexImageParametersBase(ValidationContext *context, GLint border, GLenum format, GLenum type, + GLsizei imageSize, const GLvoid *pixels); bool ValidateES3TexStorageParameters(Context *context, @@ -57,6 +58,7 @@ bool ValidateES3TexImage2DParameters(Context *context, GLint border, GLenum format, GLenum type, + GLsizei imageSize, const GLvoid *pixels); bool ValidateES3TexImage3DParameters(Context *context, @@ -153,11 +155,6 @@ bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -bool ValidES3ReadFormatType(ValidationContext *context, - GLenum internalFormat, - GLenum format, - GLenum type); - bool ValidateES3RenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); @@ -309,6 +306,12 @@ bool ValidateFlushMappedBufferRange(Context *context, GLintptr offset, GLsizeiptr length); +bool ValidateIndexedStateQuery(ValidationContext *context, GLenum pname, GLuint index); +bool ValidateGetIntegeri_v(ValidationContext *context, GLenum target, GLuint index, GLint *data); +bool ValidateGetInteger64i_v(ValidationContext *context, + GLenum target, + GLuint index, + GLint64 *data); } // namespace gl #endif // LIBANGLE_VALIDATION_ES3_H_ diff --git a/chromium/third_party/angle/src/libANGLE/validationES31.cpp b/chromium/third_party/angle/src/libANGLE/validationES31.cpp new file mode 100644 index 00000000000..f7406090d1a --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/validationES31.cpp @@ -0,0 +1,35 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters + +#include "libANGLE/validationES3.h" +#include "libANGLE/validationES31.h" + +#include "libANGLE/Context.h" + +using namespace angle; + +namespace gl +{ + +bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data) +{ + if (!context->getGLVersion().isES31()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.1")); + return false; + } + + if (!ValidateIndexedStateQuery(context, target, index)) + { + return false; + } + + return true; +} + +} // namespace gl diff --git a/chromium/third_party/angle/src/libANGLE/validationES31.h b/chromium/third_party/angle/src/libANGLE/validationES31.h new file mode 100644 index 00000000000..517720cae4e --- /dev/null +++ b/chromium/third_party/angle/src/libANGLE/validationES31.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES31.h: Validation functions for OpenGL ES 3.1 entry point parameters + +#ifndef LIBANGLE_VALIDATION_ES31_H_ +#define LIBANGLE_VALIDATION_ES31_H_ + +#include <GLES3/gl31.h> + +namespace gl +{ +class Context; + +bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data); + +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES31_H_ diff --git a/chromium/third_party/angle/src/libANGLE/validationES_unittest.cpp b/chromium/third_party/angle/src/libANGLE/validationES_unittest.cpp index fe32f39ec9e..c018924e139 100644 --- a/chromium/third_party/angle/src/libANGLE/validationES_unittest.cpp +++ b/chromium/third_party/angle/src/libANGLE/validationES_unittest.cpp @@ -29,7 +29,8 @@ namespace class MockValidationContext : public ValidationContext { public: - MockValidationContext(GLint clientVersion, + MockValidationContext(GLint majorClientVersion, + GLint minorClientVersion, State *state, const Caps &caps, const TextureCapsMap &textureCaps, @@ -41,7 +42,8 @@ class MockValidationContext : public ValidationContext MOCK_METHOD1(handleError, void(const Error &)); }; -MockValidationContext::MockValidationContext(GLint clientVersion, +MockValidationContext::MockValidationContext(GLint majorClientVersion, + GLint minorClientVersion, State *state, const Caps &caps, const TextureCapsMap &textureCaps, @@ -49,7 +51,8 @@ MockValidationContext::MockValidationContext(GLint clientVersion, const ResourceManager *resourceManager, const Limitations &limitations, bool skipValidation) - : ValidationContext(clientVersion, + : ValidationContext(majorClientVersion, + minorClientVersion, state, caps, textureCaps, @@ -84,7 +87,7 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) caps.maxElementIndex = 100; caps.maxDrawBuffers = 1; caps.maxColorAttachments = 1; - state.initialize(caps, extensions, 3, false); + state.initialize(caps, extensions, 3, false, true); NiceMock<MockTextureImpl> *textureImpl = new NiceMock<MockTextureImpl>(); EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl)); @@ -105,8 +108,8 @@ TEST(ValidationESTest, DrawElementsWithMaxIndexGivesError) state.setDrawFramebufferBinding(framebuffer); state.setProgram(program); - NiceMock<MockValidationContext> testContext(3, &state, caps, textureCaps, extensions, nullptr, - limitations, false); + NiceMock<MockValidationContext> testContext(3, 0, &state, caps, textureCaps, extensions, + nullptr, limitations, false); // Set the expectation for the validation error here. Error expectedError(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage); diff --git a/chromium/third_party/angle/src/libEGL.gypi b/chromium/third_party/angle/src/libEGL.gypi index 1d8870452a8..813b006c598 100644 --- a/chromium/third_party/angle/src/libEGL.gypi +++ b/chromium/third_party/angle/src/libEGL.gypi @@ -5,10 +5,6 @@ { # Everything below this is duplicated in the GN build. If you change # anything also change angle/BUILD.gn - 'variables': - { - 'angle_standalone%': 0, - }, 'targets': [ { diff --git a/chromium/third_party/angle/src/libGLESv2.gypi b/chromium/third_party/angle/src/libGLESv2.gypi index 710c1c18159..96a6a9dae5b 100644 --- a/chromium/third_party/angle/src/libGLESv2.gypi +++ b/chromium/third_party/angle/src/libGLESv2.gypi @@ -5,12 +5,12 @@ { 'variables': { - 'angle_standalone%': 0, - # These file lists are shared with the GN build. 'libangle_common_sources': [ 'common/BitSetIterator.h', + 'common/Color.h', + 'common/Color.inl', 'common/Float16ToFloat32.cpp', 'common/MemoryBuffer.cpp', 'common/MemoryBuffer.h', @@ -36,6 +36,20 @@ 'common/utilities.h', 'common/version.h', ], + 'libangle_image_util_sources': + [ + 'image_util/copyimage.cpp', + 'image_util/copyimage.h', + 'image_util/copyimage.inl', + 'image_util/generatemip.h', + 'image_util/generatemip.inl', + 'image_util/imageformats.cpp', + 'image_util/imageformats.h', + 'image_util/loadimage.cpp', + 'image_util/loadimage.h', + 'image_util/loadimage.inl', + 'image_util/loadimage_etc.cpp', + ], 'libangle_includes': [ '../include/angle_gl.h', @@ -139,11 +153,14 @@ 'libANGLE/angletypes.h', 'libANGLE/angletypes.inl', 'libANGLE/features.h', + 'libANGLE/format_map_autogen.cpp', 'libANGLE/formatutils.cpp', 'libANGLE/formatutils.h', 'libANGLE/histogram_macros.h', 'libANGLE/queryconversions.cpp', 'libANGLE/queryconversions.h', + 'libANGLE/queryutils.cpp', + 'libANGLE/queryutils.h', 'libANGLE/renderer/BufferImpl.h', 'libANGLE/renderer/CompilerImpl.h', 'libANGLE/renderer/ContextImpl.cpp', @@ -155,6 +172,10 @@ 'libANGLE/renderer/EGLImplFactory.h', 'libANGLE/renderer/FenceNVImpl.h', 'libANGLE/renderer/FenceSyncImpl.h', + 'libANGLE/renderer/Format_ID_autogen.inl', + 'libANGLE/renderer/Format_autogen.cpp', + 'libANGLE/renderer/Format.cpp', + 'libANGLE/renderer/Format.h', 'libANGLE/renderer/FramebufferAttachmentObjectImpl.h', 'libANGLE/renderer/FramebufferImpl.h', 'libANGLE/renderer/GLImplFactory.h', @@ -167,13 +188,12 @@ 'libANGLE/renderer/StreamProducerImpl.h', 'libANGLE/renderer/SurfaceImpl.cpp', 'libANGLE/renderer/SurfaceImpl.h', + 'libANGLE/renderer/TextureImpl.cpp', 'libANGLE/renderer/TextureImpl.h', 'libANGLE/renderer/TransformFeedbackImpl.h', 'libANGLE/renderer/VertexArrayImpl.h', - 'libANGLE/renderer/copyimage.cpp', - 'libANGLE/renderer/copyimage.h', - 'libANGLE/renderer/copyimage.inl', - 'libANGLE/renderer/imageformats.h', + 'libANGLE/renderer/load_functions_table.h', + 'libANGLE/renderer/load_functions_table_autogen.cpp', 'libANGLE/renderer/renderer_utils.cpp', 'libANGLE/renderer/renderer_utils.h', 'libANGLE/signal_utils.cpp', @@ -186,6 +206,8 @@ 'libANGLE/validationES2.h', 'libANGLE/validationES3.cpp', 'libANGLE/validationES3.h', + 'libANGLE/validationES31.cpp', + 'libANGLE/validationES31.h', 'third_party/murmurhash/MurmurHash3.cpp', 'third_party/murmurhash/MurmurHash3.h', ], @@ -206,8 +228,6 @@ 'libANGLE/renderer/d3d/formatutilsD3D.h', 'libANGLE/renderer/d3d/FramebufferD3D.cpp', 'libANGLE/renderer/d3d/FramebufferD3D.h', - 'libANGLE/renderer/d3d/generatemip.h', - 'libANGLE/renderer/d3d/generatemip.inl', 'libANGLE/renderer/d3d/HLSLCompiler.cpp', 'libANGLE/renderer/d3d/HLSLCompiler.h', 'libANGLE/renderer/d3d/ImageD3D.cpp', @@ -216,12 +236,6 @@ 'libANGLE/renderer/d3d/IndexBuffer.h', 'libANGLE/renderer/d3d/IndexDataManager.cpp', 'libANGLE/renderer/d3d/IndexDataManager.h', - 'libANGLE/renderer/d3d/loadimage.cpp', - 'libANGLE/renderer/d3d/loadimage.h', - 'libANGLE/renderer/d3d/loadimage.inl', - 'libANGLE/renderer/d3d/loadimageSSE2.cpp', - 'libANGLE/renderer/d3d/loadimage_etc.cpp', - 'libANGLE/renderer/d3d/loadimage_etc.h', 'libANGLE/renderer/d3d/NativeWindowD3D.cpp', 'libANGLE/renderer/d3d/NativeWindowD3D.h', 'libANGLE/renderer/d3d/ProgramD3D.cpp', @@ -243,8 +257,6 @@ 'libANGLE/renderer/d3d/TextureD3D.cpp', 'libANGLE/renderer/d3d/TextureD3D.h', 'libANGLE/renderer/d3d/TextureStorage.h', - 'libANGLE/renderer/d3d/TransformFeedbackD3D.cpp', - 'libANGLE/renderer/d3d/TransformFeedbackD3D.h', 'libANGLE/renderer/d3d/VaryingPacking.cpp', 'libANGLE/renderer/d3d/VaryingPacking.h', 'libANGLE/renderer/d3d/VertexBuffer.cpp', @@ -332,8 +344,6 @@ 'libANGLE/renderer/d3d/d3d11/IndexBuffer11.h', 'libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp', 'libANGLE/renderer/d3d/d3d11/InputLayoutCache.h', - 'libANGLE/renderer/d3d/d3d11/load_functions_table.h', - 'libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp', 'libANGLE/renderer/d3d/d3d11/NativeWindow11.h', 'libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp', 'libANGLE/renderer/d3d/d3d11/PixelTransfer11.h', @@ -381,12 +391,16 @@ 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h', + 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbpremultiply2d11ps.h', + 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbunmultiply2d11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h', + 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbapremultiply2d11ps.h', + 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgbaunmultiply2d11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h', 'libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h', @@ -409,10 +423,13 @@ 'libANGLE/renderer/d3d/d3d11/SwapChain11.h', 'libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp', 'libANGLE/renderer/d3d/d3d11/TextureStorage11.h', + 'libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp', + 'libANGLE/renderer/d3d/d3d11/TransformFeedback11.h', 'libANGLE/renderer/d3d/d3d11/Trim11.cpp', 'libANGLE/renderer/d3d/d3d11/Trim11.h', 'libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp', - 'libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.h', + 'libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h', + 'libANGLE/renderer/d3d/d3d11/texture_format_table.cpp', 'libANGLE/renderer/d3d/d3d11/texture_format_table.h', 'libANGLE/renderer/d3d/d3d11/VertexArray11.cpp', 'libANGLE/renderer/d3d/d3d11/VertexArray11.h', @@ -601,6 +618,47 @@ 'libANGLE/renderer/vulkan/VertexArrayVk.cpp', 'libANGLE/renderer/vulkan/VertexArrayVk.h', ], + 'libangle_null_sources': + [ + 'libANGLE/renderer/null/BufferNULL.cpp', + 'libANGLE/renderer/null/BufferNULL.h', + 'libANGLE/renderer/null/CompilerNULL.cpp', + 'libANGLE/renderer/null/CompilerNULL.h', + 'libANGLE/renderer/null/ContextNULL.cpp', + 'libANGLE/renderer/null/ContextNULL.h', + 'libANGLE/renderer/null/DeviceNULL.cpp', + 'libANGLE/renderer/null/DeviceNULL.h', + 'libANGLE/renderer/null/DisplayNULL.cpp', + 'libANGLE/renderer/null/DisplayNULL.h', + 'libANGLE/renderer/null/FenceNVNULL.cpp', + 'libANGLE/renderer/null/FenceNVNULL.h', + 'libANGLE/renderer/null/FenceSyncNULL.cpp', + 'libANGLE/renderer/null/FenceSyncNULL.h', + 'libANGLE/renderer/null/FramebufferNULL.cpp', + 'libANGLE/renderer/null/FramebufferNULL.h', + 'libANGLE/renderer/null/ImageNULL.cpp', + 'libANGLE/renderer/null/ImageNULL.h', + 'libANGLE/renderer/null/PathNULL.cpp', + 'libANGLE/renderer/null/PathNULL.h', + 'libANGLE/renderer/null/ProgramNULL.cpp', + 'libANGLE/renderer/null/ProgramNULL.h', + 'libANGLE/renderer/null/QueryNULL.cpp', + 'libANGLE/renderer/null/QueryNULL.h', + 'libANGLE/renderer/null/RenderbufferNULL.cpp', + 'libANGLE/renderer/null/RenderbufferNULL.h', + 'libANGLE/renderer/null/SamplerNULL.cpp', + 'libANGLE/renderer/null/SamplerNULL.h', + 'libANGLE/renderer/null/ShaderNULL.cpp', + 'libANGLE/renderer/null/ShaderNULL.h', + 'libANGLE/renderer/null/SurfaceNULL.cpp', + 'libANGLE/renderer/null/SurfaceNULL.h', + 'libANGLE/renderer/null/TextureNULL.cpp', + 'libANGLE/renderer/null/TextureNULL.h', + 'libANGLE/renderer/null/TransformFeedbackNULL.cpp', + 'libANGLE/renderer/null/TransformFeedbackNULL.h', + 'libANGLE/renderer/null/VertexArrayNULL.cpp', + 'libANGLE/renderer/null/VertexArrayNULL.h', + ], 'libglesv2_sources': [ 'common/angleutils.h', @@ -615,6 +673,8 @@ 'libGLESv2/entry_points_gles_2_0_ext.h', 'libGLESv2/entry_points_gles_3_0.cpp', 'libGLESv2/entry_points_gles_3_0.h', + 'libGLESv2/entry_points_gles_3_1.cpp', + 'libGLESv2/entry_points_gles_3_1.h', 'libGLESv2/global_state.cpp', 'libGLESv2/global_state.h', 'libGLESv2/libGLESv2.cpp', @@ -642,6 +702,7 @@ 'translator_static', 'commit_id', 'angle_common', + 'angle_image_util', ], 'includes': [ '../build/common_defines.gypi', ], 'include_dirs': @@ -942,6 +1003,17 @@ 'ANGLE_ENABLE_VULKAN', ], }], + ['angle_enable_null==1', + { + 'sources': + [ + '<@(libangle_null_sources)', + ], + 'defines': + [ + 'ANGLE_ENABLE_NULL', + ], + }], ['angle_build_winrt==0 and OS=="win"', { 'dependencies': @@ -974,10 +1046,6 @@ { 'msvs_requires_importlibrary' : 'true', }], - ['angle_build_winphone==1', - { - 'msvs_enable_winphone' : '1', - }], ], }, ], diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_egl.cpp b/chromium/third_party/angle/src/libGLESv2/entry_points_egl.cpp index 438ff3af17b..485e5f0ce00 100644 --- a/chromium/third_party/angle/src/libGLESv2/entry_points_egl.cpp +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_egl.cpp @@ -11,6 +11,7 @@ #include "libGLESv2/entry_points_gles_2_0.h" #include "libGLESv2/entry_points_gles_2_0_ext.h" #include "libGLESv2/entry_points_gles_3_0.h" +#include "libGLESv2/entry_points_gles_3_1.h" #include "libGLESv2/global_state.h" #include "libANGLE/Context.h" @@ -582,19 +583,10 @@ EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface r } } - if (display->isInitialized()) + if (display->isInitialized() && display->testDeviceLost()) { - if (display->testDeviceLost()) - { - display->notifyDeviceLost(); - return EGL_FALSE; - } - - if (display->isDeviceLost()) - { - SetGlobalError(Error(EGL_CONTEXT_LOST)); - return EGL_FALSE; - } + SetGlobalError(Error(EGL_CONTEXT_LOST)); + return EGL_FALSE; } Surface *drawSurface = static_cast<Surface*>(draw); @@ -728,8 +720,8 @@ EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attri *value = context->getClientType(); break; case EGL_CONTEXT_CLIENT_VERSION: - *value = context->getClientVersion(); - break; + *value = context->getClientMajorVersion(); + break; case EGL_RENDER_BUFFER: *value = context->getRenderBuffer(); break; @@ -812,7 +804,7 @@ EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface) return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { SetGlobalError(Error(EGL_CONTEXT_LOST)); return EGL_FALSE; @@ -849,7 +841,7 @@ EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNative return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { SetGlobalError(Error(EGL_CONTEXT_LOST)); return EGL_FALSE; @@ -1476,6 +1468,74 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char * // GL_CHROMIUM_bind_uniform_location INSERT_PROC_ADDRESS(gl, BindUniformLocationCHROMIUM); + // GL_CHROMIUM_copy_texture + INSERT_PROC_ADDRESS(gl, CopyTextureCHROMIUM); + INSERT_PROC_ADDRESS(gl, CopySubTextureCHROMIUM); + + // GL_ANGLE_webgl_compatibility + INSERT_PROC_ADDRESS(gl, EnableExtensionANGLE); + + // GL_ANGLE_robust_client_memory + INSERT_PROC_ADDRESS(gl, GetBooleanvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetBufferParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetFloatvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetIntegervRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetProgramivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetRenderbufferParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetShaderivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetTexParameterfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetTexParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetUniformfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetUniformivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetVertexAttribfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetVertexAttribivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetVertexAttribPointervRobustANGLE); + INSERT_PROC_ADDRESS(gl, ReadPixelsRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexImage2DRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexParameterfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexSubImage2DRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexImage3DRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexSubImage3DRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetQueryivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetQueryObjectuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetBufferPointervRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetIntegeri_vRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetVertexAttribIivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetVertexAttribIuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetUniformuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetInteger64vRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetInteger64i_vRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetBufferParameteri64vRobustANGLE); + INSERT_PROC_ADDRESS(gl, SamplerParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, SamplerParameterfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetSamplerParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetSamplerParameterfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetFramebufferParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetProgramInterfaceivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetBooleani_vRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetMultisamplefvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetTexLevelParameterivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetPointervRobustANGLERobustANGLE); + INSERT_PROC_ADDRESS(gl, ReadnPixelsRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetnUniformfvRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetnUniformivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetnUniformuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexParameterIivRobustANGLE); + INSERT_PROC_ADDRESS(gl, TexParameterIuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetTexParameterIivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetTexParameterIuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, SamplerParameterIivRobustANGLE); + INSERT_PROC_ADDRESS(gl, SamplerParameterIuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetSamplerParameterIivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetSamplerParameterIuivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetQueryObjectivRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vRobustANGLE); + INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vRobustANGLE); + // GLES3 core INSERT_PROC_ADDRESS(gl, ReadBuffer); INSERT_PROC_ADDRESS(gl, DrawRangeElements); @@ -1583,6 +1643,76 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char * INSERT_PROC_ADDRESS(gl, TexStorage3D); INSERT_PROC_ADDRESS(gl, GetInternalformativ); + // GLES31 core + INSERT_PROC_ADDRESS(gl, DispatchCompute); + INSERT_PROC_ADDRESS(gl, DispatchComputeIndirect); + INSERT_PROC_ADDRESS(gl, DrawArraysIndirect); + INSERT_PROC_ADDRESS(gl, DrawElementsIndirect); + INSERT_PROC_ADDRESS(gl, FramebufferParameteri); + INSERT_PROC_ADDRESS(gl, GetFramebufferParameteriv); + INSERT_PROC_ADDRESS(gl, GetProgramInterfaceiv); + INSERT_PROC_ADDRESS(gl, GetProgramResourceIndex); + INSERT_PROC_ADDRESS(gl, GetProgramResourceName); + INSERT_PROC_ADDRESS(gl, GetProgramResourceiv); + INSERT_PROC_ADDRESS(gl, GetProgramResourceLocation); + INSERT_PROC_ADDRESS(gl, UseProgramStages); + INSERT_PROC_ADDRESS(gl, ActiveShaderProgram); + INSERT_PROC_ADDRESS(gl, CreateShaderProgramv); + INSERT_PROC_ADDRESS(gl, BindProgramPipeline); + INSERT_PROC_ADDRESS(gl, DeleteProgramPipelines); + INSERT_PROC_ADDRESS(gl, GenProgramPipelines); + INSERT_PROC_ADDRESS(gl, IsProgramPipeline); + INSERT_PROC_ADDRESS(gl, GetProgramPipelineiv); + INSERT_PROC_ADDRESS(gl, ProgramUniform1i); + INSERT_PROC_ADDRESS(gl, ProgramUniform2i); + INSERT_PROC_ADDRESS(gl, ProgramUniform3i); + INSERT_PROC_ADDRESS(gl, ProgramUniform4i); + INSERT_PROC_ADDRESS(gl, ProgramUniform1ui); + INSERT_PROC_ADDRESS(gl, ProgramUniform2ui); + INSERT_PROC_ADDRESS(gl, ProgramUniform3ui); + INSERT_PROC_ADDRESS(gl, ProgramUniform4ui); + INSERT_PROC_ADDRESS(gl, ProgramUniform1f); + INSERT_PROC_ADDRESS(gl, ProgramUniform2f); + INSERT_PROC_ADDRESS(gl, ProgramUniform3f); + INSERT_PROC_ADDRESS(gl, ProgramUniform4f); + INSERT_PROC_ADDRESS(gl, ProgramUniform1iv); + INSERT_PROC_ADDRESS(gl, ProgramUniform2iv); + INSERT_PROC_ADDRESS(gl, ProgramUniform3iv); + INSERT_PROC_ADDRESS(gl, ProgramUniform4iv); + INSERT_PROC_ADDRESS(gl, ProgramUniform1uiv); + INSERT_PROC_ADDRESS(gl, ProgramUniform2uiv); + INSERT_PROC_ADDRESS(gl, ProgramUniform3uiv); + INSERT_PROC_ADDRESS(gl, ProgramUniform4uiv); + INSERT_PROC_ADDRESS(gl, ProgramUniform1fv); + INSERT_PROC_ADDRESS(gl, ProgramUniform2fv); + INSERT_PROC_ADDRESS(gl, ProgramUniform3fv); + INSERT_PROC_ADDRESS(gl, ProgramUniform4fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x3fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x2fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x4fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x2fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x4fv); + INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x3fv); + INSERT_PROC_ADDRESS(gl, ValidateProgramPipeline); + INSERT_PROC_ADDRESS(gl, GetProgramPipelineInfoLog); + INSERT_PROC_ADDRESS(gl, BindImageTexture); + INSERT_PROC_ADDRESS(gl, GetBooleani_v); + INSERT_PROC_ADDRESS(gl, MemoryBarrier); + INSERT_PROC_ADDRESS(gl, MemoryBarrierByRegion); + INSERT_PROC_ADDRESS(gl, TexStorage2DMultisample); + INSERT_PROC_ADDRESS(gl, GetMultisamplefv); + INSERT_PROC_ADDRESS(gl, SampleMaski); + INSERT_PROC_ADDRESS(gl, GetTexLevelParameteriv); + INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfv); + INSERT_PROC_ADDRESS(gl, BindVertexBuffer); + INSERT_PROC_ADDRESS(gl, VertexAttribFormat); + INSERT_PROC_ADDRESS(gl, VertexAttribIFormat); + INSERT_PROC_ADDRESS(gl, VertexAttribBinding); + INSERT_PROC_ADDRESS(gl, VertexBindingDivisor); + // EGL 1.0 INSERT_PROC_ADDRESS(egl, ChooseConfig); INSERT_PROC_ADDRESS(egl, CopyBuffers); diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_egl_ext.cpp b/chromium/third_party/angle/src/libGLESv2/entry_points_egl_ext.cpp index 130c419d468..c267d4a9727 100644 --- a/chromium/third_party/angle/src/libGLESv2/entry_points_egl_ext.cpp +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_egl_ext.cpp @@ -98,7 +98,7 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { SetGlobalError(Error(EGL_CONTEXT_LOST)); return EGL_FALSE; @@ -197,6 +197,17 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp } break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + if (!clientExtensions.platformANGLENULL) + { + SetGlobalError(Error(EGL_BAD_ATTRIBUTE, + "Display type " + "EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE " + "requires EGL_ANGLE_platform_angle_null.")); + return EGL_NO_DISPLAY; + } + break; + default: SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); return EGL_NO_DISPLAY; @@ -433,7 +444,13 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E dpy, attribute, value); Display *display = static_cast<Display*>(dpy); - Error error(EGL_SUCCESS); + + Error error = ValidateDisplay(display); + if (error.isError()) + { + SetGlobalError(error); + return EGL_FALSE; + } if (!display->getExtensions().deviceQuery) { diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0.cpp b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0.cpp index 542b78c2ec4..aa6a51307c0 100644 --- a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0.cpp +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0.cpp @@ -28,6 +28,7 @@ #include "libANGLE/validationES2.h" #include "libANGLE/validationES3.h" #include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" #include "common/debug.h" #include "common/utilities.h" @@ -123,6 +124,13 @@ void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer) return; } + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isBufferGenerated(buffer)) + { + context->handleError(Error(GL_INVALID_OPERATION, "Buffer was not generated")); + return; + } + switch (target) { case GL_ARRAY_BUFFER: @@ -170,6 +178,13 @@ void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer) return; } + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isFramebufferGenerated(framebuffer)) + { + context->handleError(Error(GL_INVALID_OPERATION, "Framebuffer was not generated")); + return; + } + if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) { context->bindReadFramebuffer(framebuffer); @@ -195,6 +210,13 @@ void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer) return; } + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isRenderbufferGenerated(renderbuffer)) + { + context->handleError(Error(GL_INVALID_OPERATION, "Renderbuffer was not generated")); + return; + } + context->bindRenderbuffer(renderbuffer); } } @@ -310,33 +332,33 @@ void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha switch (dstRGB) { - case GL_ZERO: - case GL_ONE: - case GL_SRC_COLOR: - case GL_ONE_MINUS_SRC_COLOR: - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - break; + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; - case GL_SRC_ALPHA_SATURATE: - if (context->getClientVersion() < 3) - { + case GL_SRC_ALPHA_SATURATE: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + break; + + default: context->handleError(Error(GL_INVALID_ENUM)); return; - } - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; } switch (srcAlpha) @@ -365,33 +387,33 @@ void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha switch (dstAlpha) { - case GL_ZERO: - case GL_ONE: - case GL_SRC_COLOR: - case GL_ONE_MINUS_SRC_COLOR: - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - break; + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; - case GL_SRC_ALPHA_SATURATE: - if (context->getClientVersion() < 3) - { + case GL_SRC_ALPHA_SATURATE: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + break; + + default: context->handleError(Error(GL_INVALID_ENUM)); return; - } - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; } if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc) @@ -427,57 +449,12 @@ void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, Context *context = GetValidGlobalContext(); if (context) { - if (size < 0) + if (!context->skipValidation() && !ValidateBufferData(context, target, size, data, usage)) { - context->handleError(Error(GL_INVALID_VALUE)); return; } - switch (usage) - { - case GL_STREAM_DRAW: - case GL_STATIC_DRAW: - case GL_DYNAMIC_DRAW: - break; - - case GL_STREAM_READ: - case GL_STREAM_COPY: - case GL_STATIC_READ: - case GL_STATIC_COPY: - case GL_DYNAMIC_READ: - case GL_DYNAMIC_COPY: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - if (!ValidBufferTarget(context, target)) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getGLState().getTargetBuffer(target); - - if (!buffer) - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - - Error error = buffer->bufferData(data, size, usage); - if (error.isError()) - { - context->handleError(error); - return; - } + context->bufferData(target, size, data, usage); } } @@ -489,58 +466,13 @@ void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, Context *context = GetValidGlobalContext(); if (context) { - if (size < 0 || offset < 0) - { - context->handleError(Error(GL_INVALID_VALUE)); - return; - } - - if (!ValidBufferTarget(context, target)) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getGLState().getTargetBuffer(target); - - if (!buffer) - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - - if (buffer->isMapped()) - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - - // Check for possible overflow of size + offset - angle::CheckedNumeric<size_t> checkedSize(size); - checkedSize += offset; - if (!checkedSize.IsValid()) - { - context->handleError(Error(GL_OUT_OF_MEMORY)); - return; - } - - if (size + offset > buffer->getSize()) - { - context->handleError(Error(GL_INVALID_VALUE)); - return; - } - - if (data == NULL) + if (!context->skipValidation() && + !ValidateBufferSubData(context, target, offset, size, data)) { return; } - Error error = buffer->bufferSubData(data, size, offset); - if (error.isError()) - { - context->handleError(error); - return; - } + context->bufferSubData(target, offset, size, data); } } @@ -748,18 +680,13 @@ GLuint GL_APIENTRY CreateShader(GLenum type) Context *context = GetValidGlobalContext(); if (context) { - switch (type) - { - case GL_FRAGMENT_SHADER: - case GL_VERTEX_SHADER: - return context->createShader(type); - default: - context->handleError(Error(GL_INVALID_ENUM)); + if (!context->skipValidation() && !ValidateCreateShader(context, type)) + { return 0; } + return context->createShader(type); } - return 0; } @@ -1012,9 +939,8 @@ void GL_APIENTRY Disable(GLenum cap) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidCap(context, cap)) + if (!context->skipValidation() && !ValidateDisable(context, cap)) { - context->handleError(Error(GL_INVALID_ENUM)); return; } @@ -1090,26 +1016,11 @@ void GL_APIENTRY Enable(GLenum cap) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidCap(context, cap)) + if (!context->skipValidation() && !ValidateEnable(context, cap)) { - context->handleError(Error(GL_INVALID_ENUM)); return; } - if (context->getLimitations().noSampleAlphaToCoverageSupport) - { - if (cap == GL_SAMPLE_ALPHA_TO_COVERAGE) - { - const char *errorMessage = "Current renderer doesn't support alpha-to-coverage"; - context->handleError(Error(GL_INVALID_OPERATION, errorMessage)); - - // We also output an error message to the debugger window if tracing is active, so that developers can see the error message. - ERR("%s", errorMessage); - - return; - } - } - context->enable(cap); } } @@ -1461,53 +1372,15 @@ void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - if (!ValidBufferParameter(context, pname)) + GLsizei numParams = 0; + if (!context->skipValidation() && + !ValidateGetBufferParameteriv(context, target, pname, &numParams)) { - context->handleError(Error(GL_INVALID_ENUM)); return; } Buffer *buffer = context->getGLState().getTargetBuffer(target); - - if (!buffer) - { - // A null buffer means that "0" is bound to the requested buffer target - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (pname) - { - case GL_BUFFER_USAGE: - *params = static_cast<GLint>(buffer->getUsage()); - break; - case GL_BUFFER_SIZE: - *params = clampCast<GLint>(buffer->getSize()); - break; - case GL_BUFFER_ACCESS_FLAGS: - *params = buffer->getAccessFlags(); - break; - case GL_BUFFER_ACCESS_OES: - *params = buffer->getAccess(); - break; - case GL_BUFFER_MAPPED: - static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal."); - *params = static_cast<GLint>(buffer->isMapped()); - break; - case GL_BUFFER_MAP_OFFSET: - *params = clampCast<GLint>(buffer->getMapOffset()); - break; - case GL_BUFFER_MAP_LENGTH: - *params = clampCast<GLint>(buffer->getMapLength()); - break; - default: UNREACHABLE(); break; - } + QueryBufferParameteriv(buffer, pname, params); } } @@ -1558,259 +1431,16 @@ void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, GLenum attac Context *context = GetValidGlobalContext(); if (context) { - if (!ValidFramebufferTarget(target)) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - int clientVersion = context->getClientVersion(); - - switch (pname) + GLsizei numParams = 0; + if (!context->skipValidation() && + !ValidateGetFramebufferAttachmentParameteriv(context, target, attachment, pname, + &numParams)) { - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: - break; - - case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: - if (clientVersion < 3 && !context->getExtensions().sRGB) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - break; - - case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: - if (clientVersion < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); return; } - // Determine if the attachment is a valid enum - switch (attachment) - { - case GL_BACK: - case GL_FRONT: - case GL_DEPTH: - case GL_STENCIL: - case GL_DEPTH_STENCIL_ATTACHMENT: - if (clientVersion < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - break; - - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - break; - - default: - if (attachment < GL_COLOR_ATTACHMENT0_EXT || - (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - break; - } - const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - if (framebuffer->id() == 0) - { - if (clientVersion < 3) - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (attachment) - { - case GL_BACK: - case GL_DEPTH: - case GL_STENCIL: - break; - - default: - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - } - else - { - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) - { - // Valid attachment query - } - else - { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - break; - - case GL_DEPTH_STENCIL_ATTACHMENT: - if (!framebuffer->hasValidDepthStencil()) - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - break; - - default: - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - } - } - - const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment); - if (attachmentObject) - { - ASSERT(attachmentObject->type() == GL_RENDERBUFFER || - attachmentObject->type() == GL_TEXTURE || - attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT); - - switch (pname) - { - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: - *params = attachmentObject->type(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - if (attachmentObject->type() != GL_RENDERBUFFER && attachmentObject->type() != GL_TEXTURE) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->id(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: - if (attachmentObject->type() != GL_TEXTURE) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->mipLevel(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: - if (attachmentObject->type() != GL_TEXTURE) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->cubeMapFace(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: - *params = attachmentObject->getRedSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: - *params = attachmentObject->getGreenSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: - *params = attachmentObject->getBlueSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: - *params = attachmentObject->getAlphaSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: - *params = attachmentObject->getDepthSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: - *params = attachmentObject->getStencilSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: - if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - *params = attachmentObject->getComponentType(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: - *params = attachmentObject->getColorEncoding(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: - if (attachmentObject->type() != GL_TEXTURE) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->layer(); - break; - - default: - UNREACHABLE(); - break; - } - } - else - { - // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE - // is NONE, then querying any other pname will generate INVALID_ENUM. - - // ES 3.0.2 spec pg 235 states that if the attachment type is none, - // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an - // INVALID_OPERATION for all other pnames - - switch (pname) - { - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: - *params = GL_NONE; - break; - - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - if (clientVersion < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = 0; - break; - - default: - if (clientVersion < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - else - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - } - } + QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params); } } @@ -1847,83 +1477,15 @@ void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params) Context *context = GetValidGlobalContext(); if (context) { - Program *programObject = GetValidProgram(context, program); - - if (!programObject) + GLsizei numParams = 0; + if (!context->skipValidation() && + !ValidateGetProgramiv(context, program, pname, &numParams)) { return; } - if (context->getClientVersion() < 3) - { - switch (pname) - { - case GL_ACTIVE_UNIFORM_BLOCKS: - case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: - case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: - case GL_TRANSFORM_FEEDBACK_VARYINGS: - case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: - case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - } - - switch (pname) - { - case GL_DELETE_STATUS: - *params = programObject->isFlaggedForDeletion(); - return; - case GL_LINK_STATUS: - *params = programObject->isLinked(); - return; - case GL_VALIDATE_STATUS: - *params = programObject->isValidated(); - return; - case GL_INFO_LOG_LENGTH: - *params = programObject->getInfoLogLength(); - return; - case GL_ATTACHED_SHADERS: - *params = programObject->getAttachedShadersCount(); - return; - case GL_ACTIVE_ATTRIBUTES: - *params = programObject->getActiveAttributeCount(); - return; - case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = programObject->getActiveAttributeMaxLength(); - return; - case GL_ACTIVE_UNIFORMS: - *params = programObject->getActiveUniformCount(); - return; - case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = programObject->getActiveUniformMaxLength(); - return; - case GL_PROGRAM_BINARY_LENGTH_OES: - *params = programObject->getBinaryLength(); - return; - case GL_ACTIVE_UNIFORM_BLOCKS: - *params = programObject->getActiveUniformBlockCount(); - return; - case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: - *params = programObject->getActiveUniformBlockMaxLength(); - break; - case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: - *params = programObject->getTransformFeedbackBufferMode(); - break; - case GL_TRANSFORM_FEEDBACK_VARYINGS: - *params = programObject->getTransformFeedbackVaryingCount(); - break; - case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: - *params = programObject->getTransformFeedbackVaryingMaxLength(); - break; - case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: - *params = programObject->getBinaryRetrievableHint(); - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; - } + Program *programObject = context->getProgram(program); + QueryProgramiv(programObject, pname, params); } } @@ -1975,28 +1537,46 @@ void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* switch (pname) { - case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; - case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; - case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break; - case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; - case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; - case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; - case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; - case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; - case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; - - case GL_RENDERBUFFER_SAMPLES_ANGLE: - if (!context->getExtensions().framebufferMultisample) - { + case GL_RENDERBUFFER_WIDTH: + *params = renderbuffer->getWidth(); + break; + case GL_RENDERBUFFER_HEIGHT: + *params = renderbuffer->getHeight(); + break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: + *params = renderbuffer->getFormat().info->internalFormat; + break; + case GL_RENDERBUFFER_RED_SIZE: + *params = renderbuffer->getRedSize(); + break; + case GL_RENDERBUFFER_GREEN_SIZE: + *params = renderbuffer->getGreenSize(); + break; + case GL_RENDERBUFFER_BLUE_SIZE: + *params = renderbuffer->getBlueSize(); + break; + case GL_RENDERBUFFER_ALPHA_SIZE: + *params = renderbuffer->getAlphaSize(); + break; + case GL_RENDERBUFFER_DEPTH_SIZE: + *params = renderbuffer->getDepthSize(); + break; + case GL_RENDERBUFFER_STENCIL_SIZE: + *params = renderbuffer->getStencilSize(); + break; + + case GL_RENDERBUFFER_SAMPLES_ANGLE: + if (!context->getExtensions().framebufferMultisample) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = renderbuffer->getSamples(); + break; + + default: context->handleError(Error(GL_INVALID_ENUM)); return; - } - *params = renderbuffer->getSamples(); - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; } } } @@ -2178,10 +1758,10 @@ const GLubyte *GL_APIENTRY GetString(GLenum name) return reinterpret_cast<const GLubyte *>("Google Inc."); case GL_RENDERER: - return reinterpret_cast<const GLubyte *>(context->getRendererString().c_str()); + return reinterpret_cast<const GLubyte *>(context->getRendererString()); case GL_VERSION: - if (context->getClientVersion() == 2) + if (context->getClientMajorVersion() == 2) { return reinterpret_cast<const GLubyte *>( "OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")"); @@ -2193,7 +1773,7 @@ const GLubyte *GL_APIENTRY GetString(GLenum name) } case GL_SHADING_LANGUAGE_VERSION: - if (context->getClientVersion() == 2) + if (context->getClientMajorVersion() == 2) { return reinterpret_cast<const GLubyte *>( "OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")"); @@ -2205,7 +1785,7 @@ const GLubyte *GL_APIENTRY GetString(GLenum name) } case GL_EXTENSIONS: - return reinterpret_cast<const GLubyte *>(context->getExtensionString().c_str()); + return reinterpret_cast<const GLubyte *>(context->getExtensionString()); default: context->handleError(Error(GL_INVALID_ENUM)); @@ -2241,132 +1821,134 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { case GL_TEXTURE_MAG_FILTER: *params = (GLfloat)texture->getMagFilter(); - break; + break; case GL_TEXTURE_MIN_FILTER: *params = (GLfloat)texture->getMinFilter(); - break; + break; case GL_TEXTURE_WRAP_S: *params = (GLfloat)texture->getWrapS(); - break; + break; case GL_TEXTURE_WRAP_T: *params = (GLfloat)texture->getWrapT(); - break; + break; case GL_TEXTURE_WRAP_R: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getWrapR(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getWrapR(); + break; case GL_TEXTURE_IMMUTABLE_FORMAT: - // Exposed to ES2.0 through EXT_texture_storage, no client version validation. - *params = (GLfloat)(texture->getImmutableFormat() ? GL_TRUE : GL_FALSE); - break; + // Exposed to ES2.0 through EXT_texture_storage, no client version validation. + *params = (GLfloat)(texture->getImmutableFormat() ? GL_TRUE : GL_FALSE); + break; case GL_TEXTURE_IMMUTABLE_LEVELS: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getImmutableLevels(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getImmutableLevels(); + break; case GL_TEXTURE_USAGE_ANGLE: - *params = (GLfloat)texture->getUsage(); - break; + *params = (GLfloat)texture->getUsage(); + break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: - if (!context->getExtensions().textureFilterAnisotropic) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getMaxAnisotropy(); - break; + if (!context->getExtensions().textureFilterAnisotropic) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getMaxAnisotropy(); + break; case GL_TEXTURE_SWIZZLE_R: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleRed(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getSwizzleRed(); + break; case GL_TEXTURE_SWIZZLE_G: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleGreen(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getSwizzleGreen(); + break; case GL_TEXTURE_SWIZZLE_B: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleBlue(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getSwizzleBlue(); + break; case GL_TEXTURE_SWIZZLE_A: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleAlpha(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getSwizzleAlpha(); + break; case GL_TEXTURE_BASE_LEVEL: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getBaseLevel(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getBaseLevel(); + break; case GL_TEXTURE_MAX_LEVEL: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getMaxLevel(); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLfloat)texture->getMaxLevel(); + break; case GL_TEXTURE_MIN_LOD: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSamplerState().minLod; - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getSamplerState().minLod; + break; case GL_TEXTURE_MAX_LOD: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSamplerState().maxLod; - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getSamplerState().maxLod; + break; case GL_TEXTURE_COMPARE_MODE: - if (context->getClientVersion() < 3) - { - context->handleError(Error( - GL_INVALID_ENUM, "GL_TEXTURE_COMPARE_MODE not available in ES versions < 3.0")); - return; - } - *params = static_cast<GLfloat>(texture->getCompareMode()); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_MODE not available in ES versions < 3.0")); + return; + } + *params = static_cast<GLfloat>(texture->getCompareMode()); + break; case GL_TEXTURE_COMPARE_FUNC: - if (context->getClientVersion() < 3) - { - context->handleError(Error( - GL_INVALID_ENUM, "GL_TEXTURE_COMPARE_FUNC not available in ES versions < 3.0")); - return; - } - *params = static_cast<GLfloat>(texture->getCompareFunc()); - break; + if (context->getClientMajorVersion() < 3) + { + context->handleError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_FUNC not available in ES versions < 3.0")); + return; + } + *params = static_cast<GLfloat>(texture->getCompareFunc()); + break; default: context->handleError(Error(GL_INVALID_ENUM)); - return; + return; } } } @@ -2394,134 +1976,136 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) switch (pname) { - case GL_TEXTURE_MAG_FILTER: - *params = texture->getSamplerState().magFilter; - break; - case GL_TEXTURE_MIN_FILTER: - *params = texture->getSamplerState().minFilter; - break; - case GL_TEXTURE_WRAP_S: - *params = texture->getSamplerState().wrapS; - break; - case GL_TEXTURE_WRAP_T: - *params = texture->getSamplerState().wrapT; - break; - case GL_TEXTURE_WRAP_R: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSamplerState().wrapR; - break; - case GL_TEXTURE_IMMUTABLE_FORMAT: - // Exposed to ES2.0 through EXT_texture_storage, no client version validation. - *params = texture->getImmutableFormat() ? GL_TRUE : GL_FALSE; - break; - case GL_TEXTURE_IMMUTABLE_LEVELS: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = static_cast<GLint>(texture->getImmutableLevels()); - break; - case GL_TEXTURE_USAGE_ANGLE: - *params = texture->getUsage(); - break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - if (!context->getExtensions().textureFilterAnisotropic) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLint)texture->getMaxAnisotropy(); - break; - case GL_TEXTURE_SWIZZLE_R: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleRed(); - break; - case GL_TEXTURE_SWIZZLE_G: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleGreen(); - break; - case GL_TEXTURE_SWIZZLE_B: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleBlue(); - break; - case GL_TEXTURE_SWIZZLE_A: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleAlpha(); - break; - case GL_TEXTURE_BASE_LEVEL: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getBaseLevel(); - break; - case GL_TEXTURE_MAX_LEVEL: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getMaxLevel(); - break; - case GL_TEXTURE_MIN_LOD: - if (context->getClientVersion() < 3) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - *params = iround<GLint>(texture->getMinLod()); - break; - case GL_TEXTURE_MAX_LOD: - if (context->getClientVersion() < 3) - { + case GL_TEXTURE_MAG_FILTER: + *params = texture->getSamplerState().magFilter; + break; + case GL_TEXTURE_MIN_FILTER: + *params = texture->getSamplerState().minFilter; + break; + case GL_TEXTURE_WRAP_S: + *params = texture->getSamplerState().wrapS; + break; + case GL_TEXTURE_WRAP_T: + *params = texture->getSamplerState().wrapT; + break; + case GL_TEXTURE_WRAP_R: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getSamplerState().wrapR; + break; + case GL_TEXTURE_IMMUTABLE_FORMAT: + // Exposed to ES2.0 through EXT_texture_storage, no client version validation. + *params = texture->getImmutableFormat() ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = static_cast<GLint>(texture->getImmutableLevels()); + break; + case GL_TEXTURE_USAGE_ANGLE: + *params = texture->getUsage(); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (!context->getExtensions().textureFilterAnisotropic) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = (GLint)texture->getMaxAnisotropy(); + break; + case GL_TEXTURE_SWIZZLE_R: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getSwizzleRed(); + break; + case GL_TEXTURE_SWIZZLE_G: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getSwizzleGreen(); + break; + case GL_TEXTURE_SWIZZLE_B: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getSwizzleBlue(); + break; + case GL_TEXTURE_SWIZZLE_A: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getSwizzleAlpha(); + break; + case GL_TEXTURE_BASE_LEVEL: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getBaseLevel(); + break; + case GL_TEXTURE_MAX_LEVEL: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = texture->getMaxLevel(); + break; + case GL_TEXTURE_MIN_LOD: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = iround<GLint>(texture->getMinLod()); + break; + case GL_TEXTURE_MAX_LOD: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + *params = iround<GLint>(texture->getMaxLod()); + break; + case GL_TEXTURE_COMPARE_MODE: + if (context->getClientMajorVersion() < 3) + { + context->handleError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_MODE not available in ES versions < 3.0")); + return; + } + *params = texture->getCompareMode(); + break; + case GL_TEXTURE_COMPARE_FUNC: + if (context->getClientMajorVersion() < 3) + { + context->handleError( + Error(GL_INVALID_ENUM, + "GL_TEXTURE_COMPARE_FUNC not available in ES versions < 3.0")); + return; + } + *params = texture->getCompareFunc(); + break; + default: context->handleError(Error(GL_INVALID_ENUM)); return; - } - *params = iround<GLint>(texture->getMaxLod()); - break; - case GL_TEXTURE_COMPARE_MODE: - if (context->getClientVersion() < 3) - { - context->handleError(Error( - GL_INVALID_ENUM, "GL_TEXTURE_COMPARE_MODE not available in ES versions < 3.0")); - return; - } - *params = texture->getCompareMode(); - break; - case GL_TEXTURE_COMPARE_FUNC: - if (context->getClientVersion() < 3) - { - context->handleError(Error( - GL_INVALID_ENUM, "GL_TEXTURE_COMPARE_FUNC not available in ES versions < 3.0")); - return; - } - *params = texture->getCompareFunc(); - break; - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; } } } @@ -2750,9 +2334,8 @@ GLboolean GL_APIENTRY IsEnabled(GLenum cap) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidCap(context, cap)) + if (!context->skipValidation() && !ValidateIsEnabled(context, cap)) { - context->handleError(Error(GL_INVALID_ENUM)); return GL_FALSE; } @@ -2903,7 +2486,7 @@ void GL_APIENTRY PixelStorei(GLenum pname, GLint param) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { switch (pname) { @@ -3872,29 +3455,29 @@ void GL_APIENTRY VertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - case GL_SHORT: - case GL_UNSIGNED_SHORT: - case GL_FIXED: - case GL_FLOAT: - break; + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_FIXED: + case GL_FLOAT: + break; - case GL_HALF_FLOAT: - case GL_INT: - case GL_UNSIGNED_INT: - case GL_INT_2_10_10_10_REV: - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (context->getClientVersion() < 3) - { + case GL_HALF_FLOAT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (context->getClientMajorVersion() < 3) + { + context->handleError(Error(GL_INVALID_ENUM)); + return; + } + break; + + default: context->handleError(Error(GL_INVALID_ENUM)); return; - } - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; } if (stride < 0) diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp index 666ea102bae..d9b2165aea7 100644 --- a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp @@ -16,6 +16,8 @@ #include "libANGLE/Framebuffer.h" #include "libANGLE/Shader.h" #include "libANGLE/Query.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" #include "libANGLE/validationES.h" #include "libANGLE/validationES2.h" @@ -27,6 +29,19 @@ namespace gl { +namespace +{ + +void SetRobustLengthParam(GLsizei *length, GLsizei value) +{ + if (length) + { + *length = value; + } +} + +} // anonymous namespace + void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -646,13 +661,14 @@ void GL_APIENTRY TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf return; } - if (context->getClientVersion() < 3 && - !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height)) + if (context->getClientMajorVersion() < 3 && + !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, + height)) { return; } - if (context->getClientVersion() >= 3 && + if (context->getClientMajorVersion() >= 3 && !ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height, 1)) { @@ -1266,11 +1282,7 @@ void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length, return; } - LabeledObject *object = context->getLabeledObject(identifier, name); - ASSERT(object != nullptr); - - std::string lbl(label, (length > 0) ? static_cast<size_t>(length) : strlen(label)); - object->setLabel(lbl); + context->objectLabel(identifier, name, length, label); } } @@ -1290,14 +1302,7 @@ GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *leng return; } - LabeledObject *object = context->getLabeledObject(identifier, name); - ASSERT(object != nullptr); - - const std::string &objectLabel = object->getLabel(); - size_t writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length()); - std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); - label[writeLength] = '\0'; - *length = static_cast<GLsizei>(writeLength); + context->getObjectLabel(identifier, name, bufSize, length, label); } } @@ -1314,11 +1319,7 @@ void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar return; } - LabeledObject *object = context->getLabeledObjectFromPtr(ptr); - ASSERT(object != nullptr); - - std::string lbl(label, (length > 0) ? static_cast<size_t>(length) : strlen(label)); - object->setLabel(lbl); + context->objectPtrLabel(ptr, length, label); } } @@ -1340,14 +1341,7 @@ void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr, return; } - LabeledObject *object = context->getLabeledObjectFromPtr(ptr); - ASSERT(object != nullptr); - - const std::string &objectLabel = object->getLabel(); - size_t writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length()); - std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); - label[writeLength] = '\0'; - *length = static_cast<GLsizei>(writeLength); + context->getObjectPtrLabel(ptr, bufSize, length, label); } } @@ -1665,4 +1659,1216 @@ ANGLE_EXPORT void GL_APIENTRY StencilThenCoverStrokePathCHROMIUM(GLuint path, } } +ANGLE_EXPORT void GL_APIENTRY CoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %d, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u, GLenum coverMode = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCoverFillPathInstanced(context, numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)) + { + return; + } + context->coverFillPathInstanced(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY CoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %d, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u, GLenum coverMode = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCoverStrokePathInstanced(context, numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)) + { + return; + } + context->coverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u, GLint reference = %d GLuint mask = %u GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, reference, mask, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilStrokePathInstanced(context, numPaths, pathNameType, paths, pathBase, + reference, mask, transformType, transformValues)) + { + return; + } + context->stencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, reference, + mask, transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u const void *paths = %p " + "GLuint pathBase = %u, GLenum fillMode = %u, GLuint mask = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, fillMode, mask, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilFillPathInstanced(context, numPaths, pathNameType, paths, pathBase, + fillMode, mask, transformType, transformValues)) + { + return; + } + context->stencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode, mask, + transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u const void *paths = %p " + "GLuint pathBase = %u, GLenum coverMode = %u, GLuint mask = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, mask, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilThenCoverFillPathInstanced(context, numPaths, pathNameType, paths, + pathBase, fillMode, mask, coverMode, + transformType, transformValues)) + { + return; + } + context->stencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, + fillMode, mask, coverMode, transformType, + transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u GLenum coverMode = %u GLint reference = %d GLuint mask = %u GLenum " + "transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, reference, mask, transformType, + transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilThenCoverStrokePathInstanced(context, numPaths, pathNameType, paths, + pathBase, reference, mask, coverMode, + transformType, transformValues)) + { + return; + } + context->stencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, + reference, mask, coverMode, transformType, + transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY BindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name) +{ + EVENT("(GLuint program = %u, GLint location = %d, const GLchar *name = %p)", program, location, + name); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateBindFragmentInputLocation(context, program, location, name)) + { + return; + } + context->bindFragmentInputLocation(program, location, name); + } +} + +ANGLE_EXPORT void GL_APIENTRY ProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + EVENT( + "(GLuint program = %u, GLint location %d, GLenum genMode = %u, GLint components = %d, " + "const GLfloat * coeffs = %p)", + program, location, genMode, components, coeffs); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateProgramPathFragmentInputGen(context, program, location, genMode, components, + coeffs)) + { + return; + } + context->programPathFragmentInputGen(program, location, genMode, components, coeffs); + } +} + +ANGLE_EXPORT void GL_APIENTRY CopyTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + EVENT( + "(GLuint sourceId = %u, GLuint destId = %u, GLint internalFormat = 0x%X, GLenum destType = " + "0x%X, GLboolean unpackFlipY = %u, GLboolean unpackPremultiplyAlpha = %u, GLboolean " + "unpackUnmultiplyAlpha = %u)", + sourceId, destId, internalFormat, destType, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCopyTextureCHROMIUM(context, sourceId, destId, internalFormat, destType, + unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha)) + { + return; + } + + context->copyTextureCHROMIUM(sourceId, destId, internalFormat, destType, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + } +} + +ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + EVENT( + "(GLuint sourceId = %u, GLuint destId = %u, , GLboolean unpackFlipY = %u, GLint xoffset = " + "%d, GLint yoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = " + "%d, GLboolean unpackPremultiplyAlpha = %u, GLboolean unpackUnmultiplyAlpha = %u)", + sourceId, destId, xoffset, yoffset, x, y, width, height, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCopySubTextureCHROMIUM(context, sourceId, destId, xoffset, yoffset, x, y, + width, height, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha)) + { + return; + } + + context->copySubTextureCHROMIUM(sourceId, destId, xoffset, yoffset, x, y, width, height, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + } +} + +GL_APICALL GLboolean GL_APIENTRY EnableExtensionANGLE(const GLchar *name) +{ + EVENT("(const GLchar *name = %p)", name); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateEnableExtensionANGLE(context, name)) + { + return GL_FALSE; + } + + return context->enableExtension(name) ? GL_TRUE : GL_FALSE; + } + + return GL_FALSE; +} + +ANGLE_EXPORT void GL_APIENTRY GetBooleanvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLboolean *params) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLboolean* params " + "= 0x%0.8p)", + pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + SetRobustLengthParam(length, 0); + + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams)) + { + return; + } + + if (nativeType == GL_BOOL) + { + context->getBooleanv(pname, params); + } + else + { + CastStateValues(context, nativeType, pname, numParams, params); + } + + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + SetRobustLengthParam(length, 0); + + GLsizei numParams = 0; + if (!ValidateGetBufferParameteriv(context, target, pname, &numParams)) + { + return; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + QueryBufferParameteriv(buffer, pname, params); + + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetFloatvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLfloat* params = " + "0x%0.8p)", + pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + SetRobustLengthParam(length, 0); + + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams)) + { + return; + } + + if (nativeType == GL_FLOAT) + { + context->getFloatv(pname, params); + } + else + { + CastStateValues(context, nativeType, pname, numParams, params); + } + + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameterivRobustANGLE(GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = " + "%d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + target, attachment, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + SetRobustLengthParam(length, 0); + + GLsizei numParams = 0; + if (!ValidateGetFramebufferAttachmentParameterivRobustANGLE(context, target, attachment, + pname, bufSize, &numParams)) + { + return; + } + + const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); + QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetIntegervRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *data) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLint* params = " + "0x%0.8p)", + pname, bufSize, length, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + SetRobustLengthParam(length, 0); + + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams)) + { + return; + } + + if (nativeType == GL_INT) + { + context->getIntegerv(pname, data); + } + else + { + CastStateValues(context, nativeType, pname, numParams, data); + } + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetProgramivRobustANGLE(GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %d, GLenum pname = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + program, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + SetRobustLengthParam(length, 0); + + GLsizei numParams = 0; + if (!ValidateGetProgramivRobustANGLE(context, program, pname, bufSize, &numParams)) + { + return; + } + + Program *programObject = context->getProgram(program); + QueryProgramiv(programObject, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY +GetShaderivRobustANGLE(GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params) +{ + EVENT( + "(GLuint shader = %d, GLenum pname = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + shader, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfvRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLfloat* params = 0x%0.8p)", + index, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + index, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointervRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer) +{ + EVENT( + "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLvoid** pointer = 0x%0.8p)", + index, pname, bufSize, length, pointer); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY ReadPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + void *pixels) +{ + EVENT( + "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLvoid* pixels = 0x%0.8p)", + x, y, width, height, format, type, bufSize, length, pixels); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexImage2DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " + "GLsizei height = %d, GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLsizei " + "bufSize = %d, const GLvoid* pixels = 0x%0.8p)", + target, level, internalformat, width, height, border, format, type, bufSize, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateTexImage2DRobust(context, target, level, internalformat, width, height, border, + format, type, bufSize, pixels)) + { + return; + } + + context->texImage2D(target, level, internalformat, width, height, border, format, type, + pixels); + } +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLfloat* params = " + "0x%0.8p)", + target, pname, bufSize, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLfloat* params = " + "0x%0.8p)", + target, pname, bufSize, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexSubImage2DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " + "GLsizei bufsize = %d, const GLvoid* pixels = 0x%0.8p)", + target, level, xoffset, yoffset, width, height, format, type, bufSize, pixels); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexImage3DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " + "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, " + "GLenum type = 0x%X, GLsizei bufsize = %d, const GLvoid* pixels = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, format, type, bufSize, pixels); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexSubImage3DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ +} + +ANGLE_EXPORT void GL_APIENTRY +GetQueryivRobustANGLE(GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint id = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + id, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetBufferPointervRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLvoid** params = 0x%0.8p)", + target, pname, bufSize, length, params); +} + +ANGLE_EXPORT void GL_APIENTRY +GetIntegeri_vRobustANGLE(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data) +{ + EVENT( + "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* data = 0x%0.8p)", + target, index, bufSize, length, data); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint index = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + index, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint index = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLuint* params = 0x%0.8p)", + index, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockivRobustANGLE(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLsizei bufsize " + "= %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + program, uniformBlockIndex, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetInteger64vRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *data) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLint64* params = " + "0x%0.8p)", + pname, bufSize, length, data); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetInteger64i_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data) +{ + EVENT( + "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint64* data = 0x%0.8p)", + target, index, bufSize, length, data); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", target, pname, + bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param) +{ + EVENT( + "(GLuint sampler = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLint* params = " + "0x%0.8p)", + sampler, pname, bufSize, param); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *param) +{ + EVENT( + "(GLuint sampler = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLfloat* params = " + "0x%0.8p)", + sampler, pname, bufSize, param); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint sampler = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint sample = %ur, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceivRobustANGLE(GLuint program, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLenum pname = 0x%X, GLsizei " + "bufsize = %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + program, programInterface, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetBooleani_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data) +{ + EVENT( + "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLboolean* data = 0x%0.8p)", + target, index, bufSize, length, data); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetMultisamplefvRobustANGLE(GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val) +{ + EVENT( + "(GLenum pname = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLfloat* val = 0x%0.8p)", + pname, index, bufSize, length, val); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterivRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, " + "GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + target, level, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfvRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, " + "GLsizei* length = 0x%0.8p, GLfloat* params = 0x%0.8p)", + target, level, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetPointervRobustANGLERobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, void **params = " + "0x%0.8p)", + pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY ReadnPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + void *data) +{ + EVENT( + "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLvoid *data = 0x%0.8p)", + x, y, width, height, format, type, bufSize, length, data); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetnUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetnUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetnUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLint *params = " + "0x%0.8p)", + target, pname, bufSize, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLuint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLuint *params = " + "0x%0.8p)", + target, pname, bufSize, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint *params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint *params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLint *param = " + "0x%0.8p)", + sampler, pname, bufSize, param); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLuint *param) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLuint *param = " + "0x%0.8p)", + sampler, pname, bufSize, param); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint *params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint *params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLuint *params = 0x%0.8p)", + id, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + EVENT( + "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint64 *params = 0x%0.8p)", + id, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params) +{ + EVENT( + "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLuint64 *params = 0x%0.8p)", + id, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + } // gl diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.h b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.h index c920bd5a011..677162d0851 100644 --- a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.h +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_2_0_ext.h @@ -179,6 +179,409 @@ ANGLE_EXPORT void GL_APIENTRY StencilThenCoverStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask, GLenum coverMode); -} +ANGLE_EXPORT void GL_APIENTRY CoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY CoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY StencilFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBAse, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY StencilStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY BindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY ProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + +// GL_CHROMIUM_copy_texture +ANGLE_EXPORT void GL_APIENTRY CopyTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId, + GLuint destId, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +// GL_ANGLE_webgl_compatibility +GL_APICALL GLboolean GL_APIENTRY EnableExtensionANGLE(const GLchar *name); + +// GL_ANGLE_robust_client_memory +ANGLE_EXPORT void GL_APIENTRY GetBooleanvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLboolean *data); +ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetFloatvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *data); +ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameterivRobustANGLE(GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetIntegervRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *data); +ANGLE_EXPORT void GL_APIENTRY GetProgramivRobustANGLE(GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetShaderivRobustANGLE(GLuint shader, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfvRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointervRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer); +ANGLE_EXPORT void GL_APIENTRY ReadPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexImage2DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY TexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params); +ANGLE_EXPORT void GL_APIENTRY TexSubImage2DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); + +ANGLE_EXPORT void GL_APIENTRY TexImage3DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexSubImage3DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY +GetQueryivRobustANGLE(GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetBufferPointervRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params); +ANGLE_EXPORT void GL_APIENTRY GetIntegeri_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockivRobustANGLE(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetInteger64vRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *data); +ANGLE_EXPORT void GL_APIENTRY GetInteger64i_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data); +ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *param); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); + +ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceivRobustANGLE(GLuint program, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetBooleani_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data); +ANGLE_EXPORT void GL_APIENTRY GetMultisamplefvRobustANGLE(GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterivRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfvRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); + +ANGLE_EXPORT void GL_APIENTRY GetPointervRobustANGLERobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params); +ANGLE_EXPORT void GL_APIENTRY ReadnPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + void *data); +ANGLE_EXPORT void GL_APIENTRY GetnUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetnUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetnUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY TexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params); +ANGLE_EXPORT void GL_APIENTRY TexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLuint *param); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params); + +} // namespace gl #endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_0.cpp b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_0.cpp index 007b3e3e298..b0570df2ce8 100644 --- a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_0.cpp +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_0.cpp @@ -227,7 +227,7 @@ GLboolean GL_APIENTRY IsQuery(GLuint id) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return GL_FALSE; @@ -504,7 +504,7 @@ void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, GLsizei samples, Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -657,7 +657,7 @@ GLboolean GL_APIENTRY IsVertexArray(GLuint array) return GL_FALSE; } -void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint* data) +void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint *data) { EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)", target, index, data); @@ -665,76 +665,11 @@ void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint* data) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateGetIntegeri_v(context, target, index, data)) { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - - const Caps &caps = context->getCaps(); - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER_START: - case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - if (index >= caps.maxTransformFeedbackSeparateAttributes) - { - context->handleError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_UNIFORM_BUFFER_START: - case GL_UNIFORM_BUFFER_SIZE: - case GL_UNIFORM_BUFFER_BINDING: - if (index >= caps.maxCombinedUniformBlocks) - { - context->handleError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); return; } - - if (!(context->getIndexedIntegerv(target, index, data))) - { - GLenum nativeType; - unsigned int numParams = 0; - if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - if (numParams == 0) - { - return; // it is known that pname is valid, but there are no parameters to return - } - - if (nativeType == GL_INT_64_ANGLEX) - { - GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min()); - GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max()); - GLint64 *int64Params = new GLint64[numParams]; - - context->getIndexedInteger64v(target, index, int64Params); - - for (unsigned int i = 0; i < numParams; ++i) - { - GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue); - data[i] = static_cast<GLint>(clampedValue); - } - - delete [] int64Params; - } - else - { - UNREACHABLE(); - } - } + context->getIntegeri_v(target, index, data); } } @@ -761,7 +696,7 @@ void GL_APIENTRY EndTransformFeedback(void) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -788,7 +723,7 @@ void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -824,6 +759,13 @@ void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLi return; } + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isBufferGenerated(buffer)) + { + context->handleError(Error(GL_INVALID_OPERATION, "Buffer was not generated")); + return; + } + switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER: @@ -876,7 +818,7 @@ void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -906,6 +848,13 @@ void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer) return; } + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isBufferGenerated(buffer)) + { + context->handleError(Error(GL_INVALID_OPERATION, "Buffer was not generated")); + return; + } + switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER: @@ -942,7 +891,7 @@ void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -990,7 +939,7 @@ void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsiz Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1026,7 +975,7 @@ void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLs Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1052,8 +1001,6 @@ void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLs case GL_UNSIGNED_SHORT: case GL_INT: case GL_UNSIGNED_INT: - case GL_INT_2_10_10_10_REV: - case GL_UNSIGNED_INT_2_10_10_10_REV: break; default: @@ -1067,12 +1014,6 @@ void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLs return; } - if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4) - { - context->handleError(Error(GL_INVALID_OPERATION)); - return; - } - // [OpenGL ES 3.0.2] Section 2.8 page 24: // An INVALID_OPERATION error is generated when a non-zero vertex array object // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, @@ -1096,7 +1037,7 @@ void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1139,7 +1080,7 @@ void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1182,7 +1123,7 @@ void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1206,7 +1147,7 @@ void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GL Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1229,7 +1170,7 @@ void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint* v) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1252,7 +1193,7 @@ void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint* v) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1296,7 +1237,7 @@ GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return -1; @@ -1496,7 +1437,7 @@ const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return NULL; @@ -1514,7 +1455,7 @@ const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index) return NULL; } - return reinterpret_cast<const GLubyte*>(context->getExtensionString(index).c_str()); + return reinterpret_cast<const GLubyte *>(context->getExtensionString(index)); } return NULL; @@ -1528,7 +1469,7 @@ void GL_APIENTRY CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1591,7 +1532,7 @@ void GL_APIENTRY GetUniformIndices(GLuint program, GLsizei uniformCount, const G Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1635,7 +1576,7 @@ void GL_APIENTRY GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1703,7 +1644,7 @@ GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar* uniformBlo Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return GL_INVALID_INDEX; @@ -1729,7 +1670,7 @@ void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockInde Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1777,7 +1718,7 @@ void GL_APIENTRY GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIn Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1808,7 +1749,7 @@ void GL_APIENTRY UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, G Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1846,7 +1787,7 @@ void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GL Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1874,7 +1815,7 @@ void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1903,7 +1844,7 @@ GLsync GL_APIENTRY FenceSync_(GLenum condition, GLbitfield flags) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return 0; @@ -1945,7 +1886,7 @@ GLboolean GL_APIENTRY IsSync(GLsync sync) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return GL_FALSE; @@ -1964,7 +1905,7 @@ void GL_APIENTRY DeleteSync(GLsync sync) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -1988,7 +1929,7 @@ GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeou Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return GL_WAIT_FAILED; @@ -2030,7 +1971,7 @@ void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2072,7 +2013,7 @@ void GL_APIENTRY GetInteger64v(GLenum pname, GLint64* params) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2104,7 +2045,7 @@ void GL_APIENTRY GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2156,71 +2097,11 @@ void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64* data) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (!context->skipValidation() && !ValidateGetInteger64i_v(context, target, index, data)) { - context->handleError(Error(GL_INVALID_OPERATION)); return; } - - const Caps &caps = context->getCaps(); - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER_START: - case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - if (index >= caps.maxTransformFeedbackSeparateAttributes) - { - context->handleError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_UNIFORM_BUFFER_START: - case GL_UNIFORM_BUFFER_SIZE: - case GL_UNIFORM_BUFFER_BINDING: - if (index >= caps.maxUniformBufferBindings) - { - context->handleError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - if (!(context->getIndexedInteger64v(target, index, data))) - { - GLenum nativeType; - unsigned int numParams = 0; - if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) - { - context->handleError(Error(GL_INVALID_ENUM)); - return; - } - - if (numParams == 0) - return; // it is known that pname is valid, but there are no parameters to return - - if (nativeType == GL_INT) - { - GLint *intParams = new GLint[numParams]; - - context->getIndexedIntegerv(target, index, intParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - data[i] = static_cast<GLint64>(intParams[i]); - } - - delete [] intParams; - } - else - { - UNREACHABLE(); - } - } + context->getInteger64i_v(target, index, data); } } @@ -2232,7 +2113,7 @@ void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2244,7 +2125,8 @@ void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* pa return; } - if (!ValidBufferParameter(context, pname)) + GLsizei numParams = 0; + if (!ValidBufferParameter(context, pname, &numParams)) { context->handleError(Error(GL_INVALID_ENUM)); return; @@ -2329,7 +2211,7 @@ GLboolean GL_APIENTRY IsSampler(GLuint sampler) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return GL_FALSE; @@ -2348,7 +2230,7 @@ void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2421,7 +2303,7 @@ void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* para Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2449,7 +2331,7 @@ void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* pa Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2477,7 +2359,7 @@ void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2500,7 +2382,7 @@ void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2584,7 +2466,7 @@ GLboolean GL_APIENTRY IsTransformFeedback(GLuint id) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return GL_FALSE; @@ -2611,7 +2493,7 @@ void GL_APIENTRY PauseTransformFeedback(void) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2638,7 +2520,7 @@ void GL_APIENTRY ResumeTransformFeedback(void) Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2771,7 +2653,7 @@ void GL_APIENTRY TexStorage2D(GLenum target, GLsizei levels, GLenum internalform Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2803,7 +2685,7 @@ void GL_APIENTRY TexStorage3D(GLenum target, GLsizei levels, GLenum internalform Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; @@ -2835,7 +2717,7 @@ void GL_APIENTRY GetInternalformativ(GLenum target, GLenum internalformat, GLenu Context *context = GetValidGlobalContext(); if (context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { context->handleError(Error(GL_INVALID_OPERATION)); return; diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_1.cpp b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_1.cpp new file mode 100644 index 00000000000..ae0405e992c --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_1.cpp @@ -0,0 +1,1201 @@ +// +// Copyright(c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// entry_points_gles_3_1.cpp : Implements the GLES 3.1 Entry point. + +#include "libGLESv2/entry_points_gles_3_1.h" +#include "libGLESv2/global_state.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Error.h" + +#include "libANGLE/validationES31.h" + +#include "common/debug.h" + +namespace gl +{ + +void GL_APIENTRY DispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) +{ + EVENT("(GLuint numGroupsX = %u, GLuint numGroupsY = %u, numGroupsZ = %u", numGroupsX, + numGroupsY, numGroupsZ); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect) +{ + EVENT("(GLintptr indirect = %d)", indirect); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect) +{ + EVENT("(GLenum mode = 0x%X, const void* indirect)", mode, indirect); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) +{ + EVENT("(GLenum mode = 0x%X, GLenum type = 0x%X, const void* indirect)", mode, type, indirect); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, + params); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GetProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLenum pname = 0x%X, GLint* params " + "= 0x%0.8p)", + program, programInterface, pname, params); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar* name = 0x%0.8p)", + program, programInterface, name); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } + return 0u; +} + +void GL_APIENTRY GetProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei bufSize " + "= %d, GLsizei* length = 0x%0.8p, GLchar* name = 0x%0.8p)", + program, programInterface, index, bufSize, length, name); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GetProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei " + "propCount = %d, const GLenum* props = 0x%0.8p, GLsizei bufSize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + program, programInterface, index, propCount, props, bufSize, length, params); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +GLint GL_APIENTRY GetProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar* name = 0x%0.8p)", + program, programInterface, name); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } + return 0; +} + +void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + EVENT("(GLuint pipeline = %u, GLbitfield stages = 0x%X, GLuint program = %u)", pipeline, stages, + program); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program) +{ + EVENT("(GLuint pipeline = %u, GLuint program = %u)", pipeline, program); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings) +{ + EVENT("(GLenum type = %0x%X, GLsizei count = %d, const GLchar *const* = 0x%0.8p)", type, count, + strings); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } + return 0u; +} + +void GL_APIENTRY BindProgramPipeline(GLuint pipeline) +{ + EVENT("(GLuint pipeline = %u)", pipeline); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines) +{ + EVENT("(GLsizei n = %d, const GLuint* pipelines = 0x%0.8p)", n, pipelines); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines) +{ + EVENT("(GLsizei n = %d, GLuint* pipelines = 0x%0.8p)", n, pipelines); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline) +{ + EVENT("(GLuint pipeline = %u)", pipeline); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } + return false; +} + +void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) +{ + EVENT("(GLuint pipeline = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pipeline, pname, + params); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d)", program, location, v0); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d)", program, + location, v0, v1); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d)", + program, location, v0, v1, v2); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY +ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d, " + "GLint v3 = %d)", + program, location, v0, v1, v2, v3); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLuint v0 = %u)", program, location, v0); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u)", program, + location, v0, v1); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = " + "%u)", + program, location, v0, v1, v2); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY +ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = " + "%u, GLuint v3 = %u)", + program, location, v0, v1, v2, v3); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLfloat v0 = %g)", program, location, v0); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLfloat v0 = %g, GLfloat v1 = %g)", program, + location, v0, v1); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY +ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLfloat v0 = %g, GLfloat v1 = %g, GLfloat v2 = " + "%g)", + program, location, v0, v1, v2); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY +ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLfloat v0 = %g, GLfloat v1 = %g, GLfloat v2 = " + "%g, GLfloat v3 = %g)", + program, location, v0, v1, v2, v3); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform1iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform2iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform3iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform4iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform1uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform2uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform3uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform4uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform1fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform2fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform3fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniform4fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat* value = " + "0x%0.8p)", + program, location, count, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat* value = 0x%0.8p)", + program, location, count, transpose, value); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline) +{ + EVENT("(GLuint pipeline = %u)", pipeline); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + EVENT( + "(GLuint pipeline = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* infoLog = " + "0x%0.8p)", + pipeline, bufSize, length, infoLog); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY BindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + EVENT( + "(GLuint unit = %u, GLuint texture = %u, GLint level = %d, GLboolean layered = %u, GLint " + "layer = %d, GLenum access = 0x%X, GLenum format = 0x%X)", + unit, texture, level, layered, layer, access, format); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLboolean* data = 0x%0.8p)", target, index, + data); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateGetBooleani_v(context, target, index, data)) + { + return; + } + context->getBooleani_v(target, index, data); + } +} + +void GL_APIENTRY MemoryBarrier(GLbitfield barriers) +{ + EVENT("(GLbitfield barriers = 0x%X)", barriers); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers) +{ + EVENT("(GLbitfield barriers = 0x%X)", barriers); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY TexStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + EVENT( + "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width " + "= %d, GLsizei height = %d, GLboolean fixedsamplelocations = %u)", + target, samples, internalformat, width, height, fixedsamplelocations); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val) +{ + EVENT("(GLenum pname = 0x%X, GLuint index = %u, GLfloat* val = 0x%0.8p)", pname, index, val); + UNIMPLEMENTED(); +} + +void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask) +{ + EVENT("(GLuint maskNumber = %u, GLbitfield mask = 0x%X)", maskNumber, mask); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", + target, level, pname, params); + UNIMPLEMENTED(); +} + +void GL_APIENTRY GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", + target, level, pname, params); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY BindVertexBuffer(GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride) +{ + EVENT( + "(GLuint bindingindex = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizei stride = %d)", + bindingindex, buffer, offset, stride); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY VertexAttribFormat(GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset) +{ + EVENT( + "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLboolean normalized = %u, " + "GLuint relativeoffset = %u)", + attribindex, size, type, normalized, relativeoffset); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY VertexAttribIFormat(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + EVENT( + "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLuint relativeoffset = " + "%u)", + attribindex, size, type, relativeoffset); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + EVENT("(GLuint attribindex = %u, GLuint bindingindex = %u)", attribindex, bindingindex); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} + +void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + EVENT("(GLuint bindingindex = %u, GLuint divisor = %u)", bindingindex, divisor); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + context->handleError(Error(GL_INVALID_OPERATION, "Entry point not implemented")); + } + UNIMPLEMENTED(); + } +} +} // namespace gl diff --git a/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_1.h b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_1.h new file mode 100644 index 00000000000..1500fdee84d --- /dev/null +++ b/chromium/third_party/angle/src/libGLESv2/entry_points_gles_3_1.h @@ -0,0 +1,229 @@ +// +// Copyright(c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// entry_points_gles_3_1.h : Defines the GLES 3.1 entry points. + +#ifndef LIBGLESV2_ENTRYPOINTGLES31_H_ +#define LIBGLESV2_ENTRYPOINTGLES31_H_ + +#include <GLES3/gl31.h> +#include <export.h> + +// we include the platform.h header since it undefines the conflicting MemoryBarrier macro +#include "common/platform.h" + +namespace gl +{ + +ANGLE_EXPORT void GL_APIENTRY DispatchCompute(GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ); +ANGLE_EXPORT void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect); +ANGLE_EXPORT void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect); +ANGLE_EXPORT void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect); +ANGLE_EXPORT void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param); +ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params); +ANGLE_EXPORT GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program, + GLenum programInterface, + const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT GLint GL_APIENTRY GetProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program); +ANGLE_EXPORT void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program); +ANGLE_EXPORT GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, + GLsizei count, + const GLchar *const *strings); +ANGLE_EXPORT void GL_APIENTRY BindProgramPipeline(GLuint pipeline); +ANGLE_EXPORT void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines); +ANGLE_EXPORT void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines); +ANGLE_EXPORT GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline); +ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2ui(GLuint program, + GLint location, + GLuint v0, + GLuint v1); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2f(GLuint program, + GLint location, + GLfloat v0, + GLfloat v1); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform3iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform4iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform3uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform4uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform3fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform4fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline); +ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +ANGLE_EXPORT void GL_APIENTRY BindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); +ANGLE_EXPORT void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data); + +ANGLE_EXPORT void GL_APIENTRY MemoryBarrier(GLbitfield barriers); +ANGLE_EXPORT void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers); +ANGLE_EXPORT void GL_APIENTRY TexStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +ANGLE_EXPORT void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val); +ANGLE_EXPORT void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameteriv(GLenum target, + GLint level, + GLenum pname, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfv(GLenum target, + GLint level, + GLenum pname, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY BindVertexBuffer(GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride); +ANGLE_EXPORT void GL_APIENTRY VertexAttribFormat(GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset); +ANGLE_EXPORT void GL_APIENTRY VertexAttribIFormat(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +ANGLE_EXPORT void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex); +ANGLE_EXPORT void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor); +}; + +#endif // LIBGLESV2_ENTRYPOINTGLES31_H_ diff --git a/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp b/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp index 6f5d326bd52..1d9a2d6ad75 100644 --- a/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp +++ b/chromium/third_party/angle/src/libGLESv2/libGLESv2.cpp @@ -9,6 +9,7 @@ #include "libGLESv2/entry_points_gles_2_0.h" #include "libGLESv2/entry_points_gles_2_0_ext.h" #include "libGLESv2/entry_points_gles_3_0.h" +#include "libGLESv2/entry_points_gles_3_1.h" #include "common/event_tracer.h" @@ -1572,7 +1573,6 @@ void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components) { return gl::CoverageModulationCHROMIUM(components); } -} // CHROMIUM_path_rendendering void GL_APIENTRY glMatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *matrix) @@ -1669,4 +1669,563 @@ void GL_APIENTRY glStencilThenCoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) { gl::StencilThenCoverStrokePathCHROMIUM(path, reference, mask, coverMode); -}
\ No newline at end of file +} + +void GL_APIENTRY glCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::CoverFillPathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); +} + +void GL_APIENTRY glCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::CoverStrokePathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); +} + +void GL_APIENTRY glStencilFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilFillPathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, fillMode, mask, + transformType, transformValues); +} + +void GL_APIENTRY glStencilStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilStrokePathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, reference, mask, + transformType, transformValues); +} + +void GL_APIENTRY glStencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilThenCoverFillPathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, fillMode, + mask, coverMode, transformType, transformValues); +} + +void GL_APIENTRY glStencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilThenCoverStrokePathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, + reference, mask, coverMode, transformType, + transformValues); +} + +void GL_APIENTRY glBindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name) +{ + gl::BindFragmentInputLocationCHROMIUM(program, location, name); +} + +void GL_APIENTRY glProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + gl::ProgramPathFragmentInputGenCHROMIUM(program, location, genMode, components, coeffs); +} + +// GLES 3.1 +void GL_APIENTRY glDispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) +{ + gl::DispatchCompute(numGroupsX, numGroupsY, numGroupsZ); +} + +void GL_APIENTRY glDispatchComputeIndirect(GLintptr indirect) +{ + gl::DispatchComputeIndirect(indirect); +} + +void GL_APIENTRY glDrawArraysIndirect(GLenum mode, const void *indirect) +{ + gl::DrawArraysIndirect(mode, indirect); +} + +void GL_APIENTRY glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) +{ + gl::DrawElementsIndirect(mode, type, indirect); +} + +void GL_APIENTRY glFramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + gl::FramebufferParameteri(target, pname, param); +} + +void GL_APIENTRY glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + gl::GetFramebufferParameteriv(target, pname, params); +} + +void GL_APIENTRY glGetProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + gl::GetProgramInterfaceiv(program, programInterface, pname, params); +} + +GLuint GL_APIENTRY glGetProgramResourceIndex(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + return gl::GetProgramResourceIndex(program, programInterface, name); +} + +void GL_APIENTRY glGetProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + gl::GetProgramResourceName(program, programInterface, index, bufSize, length, name); +} + +void GL_APIENTRY glGetProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + gl::GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, + params); +} + +GLint GL_APIENTRY glGetProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + return gl::GetProgramResourceLocation(program, programInterface, name); +} + +void GL_APIENTRY glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + gl::UseProgramStages(pipeline, stages, program); +} + +void GL_APIENTRY glActiveShaderProgram(GLuint pipeline, GLuint program) +{ + gl::ActiveShaderProgram(pipeline, program); +} + +GLuint GL_APIENTRY glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings) +{ + return gl::CreateShaderProgramv(type, count, strings); +} + +void GL_APIENTRY glBindProgramPipeline(GLuint pipeline) +{ + gl::BindProgramPipeline(pipeline); +} + +void GL_APIENTRY glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines) +{ + gl::DeleteProgramPipelines(n, pipelines); +} + +void GL_APIENTRY glGenProgramPipelines(GLsizei n, GLuint *pipelines) +{ + gl::GenProgramPipelines(n, pipelines); +} + +GLboolean GL_APIENTRY glIsProgramPipeline(GLuint pipeline) +{ + return gl::IsProgramPipeline(pipeline); +} + +void GL_APIENTRY glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) +{ + gl::GetProgramPipelineiv(pipeline, pname, params); +} + +void GL_APIENTRY glProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + gl::ProgramUniform1i(program, location, v0); +} + +void GL_APIENTRY glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + gl::ProgramUniform2i(program, location, v0, v1); +} + +void GL_APIENTRY glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + gl::ProgramUniform3i(program, location, v0, v1, v2); +} + +void GL_APIENTRY +glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + gl::ProgramUniform4i(program, location, v0, v1, v2, v3); +} + +void GL_APIENTRY glProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + gl::ProgramUniform1ui(program, location, v0); +} + +void GL_APIENTRY glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + gl::ProgramUniform2ui(program, location, v0, v1); +} + +void GL_APIENTRY +glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + gl::ProgramUniform3ui(program, location, v0, v1, v2); +} + +void GL_APIENTRY +glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + gl::ProgramUniform4ui(program, location, v0, v1, v2, v3); +} + +void GL_APIENTRY glProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + gl::ProgramUniform1f(program, location, v0); +} + +void GL_APIENTRY glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + gl::ProgramUniform2f(program, location, v0, v1); +} + +void GL_APIENTRY +glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + gl::ProgramUniform3f(program, location, v0, v1, v2); +} + +void GL_APIENTRY +glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + gl::ProgramUniform4f(program, location, v0, v1, v2, v3); +} + +void GL_APIENTRY glProgramUniform1iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform1iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform2iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform2iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform3iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform3iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform4iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform4iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform1uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform1uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform2uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform2uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform3uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform3uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform4uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform4uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform1fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform1fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform2fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform2fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform3fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform3fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform4fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform4fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix2fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix3fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix4fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix2x3fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix3x2fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix2x4fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix4x2fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix3x4fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix4x3fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glValidateProgramPipeline(GLuint pipeline) +{ + gl::ValidateProgramPipeline(pipeline); +} + +void GL_APIENTRY glGetProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + gl::GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); +} + +void GL_APIENTRY glBindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + gl::BindImageTexture(unit, texture, level, layered, layer, access, format); +} + +void GL_APIENTRY glGetBooleani_v(GLenum target, GLuint index, GLboolean *data) +{ + gl::GetBooleani_v(target, index, data); +} + +void GL_APIENTRY glMemoryBarrier(GLbitfield barriers) +{ + gl::MemoryBarrier(barriers); +} + +void GL_APIENTRY glMemoryBarrierByRegion(GLbitfield barriers) +{ + gl::MemoryBarrierByRegion(barriers); +} + +void GL_APIENTRY glTexStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + gl::TexStorage2DMultisample(target, samples, internalformat, width, height, + fixedsamplelocations); +} + +void GL_APIENTRY glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val) +{ + gl::GetMultisamplefv(pname, index, val); +} + +void GL_APIENTRY glSampleMaski(GLuint maskNumber, GLbitfield mask) +{ + gl::SampleMaski(maskNumber, mask); +} + +void GL_APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) +{ + gl::GetTexLevelParameteriv(target, level, pname, params); +} + +void GL_APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) +{ + gl::GetTexLevelParameterfv(target, level, pname, params); +} + +void GL_APIENTRY glBindVertexBuffer(GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride) +{ + gl::BindVertexBuffer(bindingindex, buffer, offset, stride); +} + +void GL_APIENTRY glVertexAttribFormat(GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset) +{ + gl::VertexAttribFormat(attribindex, size, type, normalized, relativeoffset); +} + +void GL_APIENTRY glVertexAttribIFormat(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + gl::VertexAttribIFormat(attribindex, size, type, relativeoffset); +} + +void GL_APIENTRY glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + gl::VertexAttribBinding(attribindex, bindingindex); +} + +void GL_APIENTRY glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + gl::VertexBindingDivisor(bindingindex, divisor); +} +} // extern "C" diff --git a/chromium/third_party/angle/src/libGLESv2/libGLESv2.def b/chromium/third_party/angle/src/libGLESv2/libGLESv2.def index 716303b8e73..3996b95557a 100644 --- a/chromium/third_party/angle/src/libGLESv2/libGLESv2.def +++ b/chromium/third_party/angle/src/libGLESv2/libGLESv2.def @@ -220,8 +220,16 @@ EXPORTS glStencilStrokePathCHROMIUM @332 glCoverFillPathCHROMIUM @333 glCoverStrokePathCHROMIUM @334 - glStencilThenCoverFillPathCHROMIUM @335 - glStencilThenCoverStrokePathCHROMIUM @336 + glStencilThenCoverFillPathCHROMIUM @335 + glStencilThenCoverStrokePathCHROMIUM @336 + glCoverFillPathInstancedCHROMIUM @337 + glCoverStrokePathInstancedCHROMIUM @338 + glStencilStrokePathInstancedCHROMIUM @339 + glStencilFillPathInstancedCHROMIUM @340 + glStencilThenCoverFillPathInstancedCHROMIUM @341 + glStencilThenCoverStrokePathInstancedCHROMIUM @342 + glBindFragmentInputLocationCHROMIUM @343 + glProgramPathFragmentInputGenCHROMIUM @344 ; GLES 3.0 Functions glReadBuffer @180 @@ -329,6 +337,76 @@ EXPORTS glTexStorage3D @282 glGetInternalformativ @283 + ; GLES 3.1 Functions + glDispatchCompute @345 + glDispatchComputeIndirect @346 + glDrawArraysIndirect @347 + glDrawElementsIndirect @348 + glFramebufferParameteri @349 + glGetFramebufferParameteriv @350 + glGetProgramInterfaceiv @351 + glGetProgramResourceIndex @352 + glGetProgramResourceName @353 + glGetProgramResourceiv @354 + glGetProgramResourceLocation @355 + glUseProgramStages @356 + glActiveShaderProgram @357 + glCreateShaderProgramv @358 + glBindProgramPipeline @359 + glDeleteProgramPipelines @360 + glGenProgramPipelines @361 + glIsProgramPipeline @362 + glGetProgramPipelineiv @363 + glProgramUniform1i @364 + glProgramUniform2i @365 + glProgramUniform3i @366 + glProgramUniform4i @367 + glProgramUniform1ui @368 + glProgramUniform2ui @369 + glProgramUniform3ui @370 + glProgramUniform4ui @371 + glProgramUniform1f @372 + glProgramUniform2f @373 + glProgramUniform3f @374 + glProgramUniform4f @375 + glProgramUniform1iv @376 + glProgramUniform2iv @377 + glProgramUniform3iv @378 + glProgramUniform4iv @379 + glProgramUniform1uiv @380 + glProgramUniform2uiv @381 + glProgramUniform3uiv @382 + glProgramUniform4uiv @383 + glProgramUniform1fv @384 + glProgramUniform2fv @385 + glProgramUniform3fv @386 + glProgramUniform4fv @387 + glProgramUniformMatrix2fv @388 + glProgramUniformMatrix3fv @389 + glProgramUniformMatrix4fv @390 + glProgramUniformMatrix2x3fv @391 + glProgramUniformMatrix3x2fv @392 + glProgramUniformMatrix2x4fv @393 + glProgramUniformMatrix4x2fv @394 + glProgramUniformMatrix3x4fv @395 + glProgramUniformMatrix4x3fv @396 + glValidateProgramPipeline @397 + glGetProgramPipelineInfoLog @398 + glBindImageTexture @399 + glGetBooleani_v @400 + glMemoryBarrier @401 + glMemoryBarrierByRegion @402 + glTexStorage2DMultisample @403 + glGetMultisamplefv @404 + glSampleMaski @405 + glGetTexLevelParameteriv @406 + glGetTexLevelParameterfv @407 + glBindVertexBuffer @408 + glVertexAttribFormat @409 + glVertexAttribIFormat @410 + glVertexAttribBinding @411 + glVertexBindingDivisor @412 + ; ANGLE Platform Implementation ANGLEPlatformCurrent @290 ANGLEPlatformInitialize @291 diff --git a/chromium/third_party/angle/src/tests/BUILD.gn b/chromium/third_party/angle/src/tests/BUILD.gn index 2237216fa78..277d5f5b4c0 100644 --- a/chromium/third_party/angle/src/tests/BUILD.gn +++ b/chromium/third_party/angle/src/tests/BUILD.gn @@ -25,6 +25,7 @@ test("angle_unittests") { if (angle_enable_hlsl) { sources += rebase_path(unittests_gypi.angle_unittests_hlsl_sources, ".", "../..") + defines = [ "ANGLE_ENABLE_HLSL" ] } sources += [ "//gpu/angle_unittest_main.cc" ] @@ -171,13 +172,17 @@ if (build_angle_deqp_tests) { defines = deqp_gypi.deqp_defines defines += [ "_MBCS" ] + # Ask the system headers to expose all the regular function otherwise + # dEQP doesn't compile and produces warnings about implicitly defined + # functions. if (is_linux) { - # Ask the system headers to expose all the regular function otherwise - # dEQP doesn't compile and produces warnings about implicitly defined - # functions. # This has to be GNU_SOURCE as on Linux dEQP uses syscall() defines += [ "_GNU_SOURCE" ] } + if (is_android) { + # _XOPEN_SOURCE=600 is what is used in deqp/src/Android.mk + defines += [ "_XOPEN_SOURCE=600" ] + } } deqp_undefine_configs = [ @@ -193,7 +198,7 @@ if (build_angle_deqp_tests) { ] } - if (is_linux) { + if (is_linux || is_android) { deqp_undefine_configs += [ "//build/config/gcc:no_exceptions" ] } @@ -229,10 +234,13 @@ if (build_angle_deqp_tests) { if (is_win) { sources += rebase_path(deqp_gypi.deqp_libtester_sources_win, ".", "../..") } - if (is_linux) { + if (is_linux || is_android) { sources += rebase_path(deqp_gypi.deqp_libtester_sources_unix, ".", "../..") } + if (is_android) { + libs = [ "log" ] + } } config("angle_deqp_gtest_support_config") { @@ -262,16 +270,19 @@ if (build_angle_deqp_tests) { api_names = [ "gles2", "gles3", + "gles31", "egl", ] target_defines = [ "ANGLE_DEQP_GLES2_TESTS", "ANGLE_DEQP_GLES3_TESTS", + "ANGLE_DEQP_GLES31_TESTS", "ANGLE_DEQP_EGL_TESTS", ] target_sources = [ deqp_gypi.deqp_gles2_sources, deqp_gypi.deqp_gles3_sources, + deqp_gypi.deqp_gles31_sources, deqp_gypi.deqp_egl_sources, ] @@ -280,6 +291,7 @@ if (build_angle_deqp_tests) { 0, 1, 2, + 3, ]) { api_name = api_names[index] config_name = "angle_deqp_lib${api_name}_config" @@ -291,6 +303,7 @@ if (build_angle_deqp_tests) { shared_library(shared_library_name) { deps = [ ":angle_deqp_libtester", + "//third_party/angle:angle_util", ] configs -= deqp_undefine_configs @@ -326,6 +339,10 @@ if (build_angle_deqp_tests) { # Set rpath to find *.so files even in a non-component build. configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ] } + + if (is_android) { + use_native_activity = true + } } } } diff --git a/chromium/third_party/angle/src/tests/angle_end2end_tests.gypi b/chromium/third_party/angle/src/tests/angle_end2end_tests.gypi index a5be4bc7409..39c926d7d1e 100644 --- a/chromium/third_party/angle/src/tests/angle_end2end_tests.gypi +++ b/chromium/third_party/angle/src/tests/angle_end2end_tests.gypi @@ -15,6 +15,7 @@ { 'angle_end2end_tests_sources': [ + '<(angle_path)/src/tests/gl_tests/BindGeneratesResourceTest.cpp', '<(angle_path)/src/tests/gl_tests/BindUniformLocationTest.cpp', '<(angle_path)/src/tests/gl_tests/BlendMinMaxTest.cpp', '<(angle_path)/src/tests/gl_tests/BlitFramebufferANGLETest.cpp', @@ -22,8 +23,9 @@ '<(angle_path)/src/tests/gl_tests/BuiltinVariableTest.cpp', '<(angle_path)/src/tests/gl_tests/ClearTest.cpp', '<(angle_path)/src/tests/gl_tests/ColorMaskTest.cpp', - '<(angle_path)/src/tests/gl_tests/CompressedTextureTest.cpp', + '<(angle_path)/src/tests/gl_tests/ComputeShaderTest.cpp', '<(angle_path)/src/tests/gl_tests/CopyTexImageTest.cpp', + '<(angle_path)/src/tests/gl_tests/CopyTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/CubeMapTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/DebugMarkerTest.cpp', '<(angle_path)/src/tests/gl_tests/DebugTest.cpp', @@ -31,6 +33,7 @@ '<(angle_path)/src/tests/gl_tests/DiscardFramebufferEXTTest.cpp', '<(angle_path)/src/tests/gl_tests/DrawBuffersTest.cpp', '<(angle_path)/src/tests/gl_tests/DrawElementsTest.cpp', + '<(angle_path)/src/tests/gl_tests/DXT1CompressedTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/ETCTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/FenceSyncTests.cpp', '<(angle_path)/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp', @@ -58,6 +61,7 @@ '<(angle_path)/src/tests/gl_tests/ProgramBinaryTest.cpp', '<(angle_path)/src/tests/gl_tests/ReadPixelsTest.cpp', '<(angle_path)/src/tests/gl_tests/RendererTest.cpp', + '<(angle_path)/src/tests/gl_tests/RobustClientMemoryTest.cpp', '<(angle_path)/src/tests/gl_tests/SimpleOperationTest.cpp', '<(angle_path)/src/tests/gl_tests/SixteenBppTextureTest.cpp', '<(angle_path)/src/tests/gl_tests/SRGBTextureTest.cpp', @@ -73,9 +77,11 @@ '<(angle_path)/src/tests/gl_tests/UnpackRowLength.cpp', '<(angle_path)/src/tests/gl_tests/VertexAttributeTest.cpp', '<(angle_path)/src/tests/gl_tests/ViewportTest.cpp', + '<(angle_path)/src/tests/gl_tests/WebGLCompatibilityTest.cpp', '<(angle_path)/src/tests/egl_tests/EGLContextCompatibilityTest.cpp', '<(angle_path)/src/tests/egl_tests/EGLContextSharingTest.cpp', '<(angle_path)/src/tests/egl_tests/EGLQueryContextTest.cpp', + '<(angle_path)/src/tests/egl_tests/EGLRobustnessTest.cpp', '<(angle_path)/src/tests/egl_tests/EGLSanityCheckTest.cpp', '<(angle_path)/src/tests/egl_tests/EGLSurfaceTest.cpp', '<(angle_path)/src/tests/test_utils/ANGLETest.cpp', diff --git a/chromium/third_party/angle/src/tests/angle_perftests.gypi b/chromium/third_party/angle/src/tests/angle_perftests.gypi index 5252adde898..6a86da9c09c 100644 --- a/chromium/third_party/angle/src/tests/angle_perftests.gypi +++ b/chromium/third_party/angle/src/tests/angle_perftests.gypi @@ -27,6 +27,7 @@ '<(angle_path)/src/tests/perf_tests/PointSprites.cpp', '<(angle_path)/src/tests/perf_tests/TexSubImage.cpp', '<(angle_path)/src/tests/perf_tests/TextureSampling.cpp', + '<(angle_path)/src/tests/perf_tests/TexturesPerf.cpp', '<(angle_path)/src/tests/perf_tests/UniformsPerf.cpp', '<(angle_path)/src/tests/perf_tests/third_party/perf/perf_test.cc', '<(angle_path)/src/tests/perf_tests/third_party/perf/perf_test.h', diff --git a/chromium/third_party/angle/src/tests/angle_unittests.gypi b/chromium/third_party/angle/src/tests/angle_unittests.gypi index 0a5d2e87c02..f73c9dc19ac 100644 --- a/chromium/third_party/angle/src/tests/angle_unittests.gypi +++ b/chromium/third_party/angle/src/tests/angle_unittests.gypi @@ -42,10 +42,10 @@ '<(angle_path)/src/libANGLE/validationES_unittest.cpp', '<(angle_path)/src/tests/angle_unittests_utils.h', '<(angle_path)/src/tests/compiler_tests/API_test.cpp', - '<(angle_path)/src/tests/compiler_tests/BuiltInFunctionEmulator_test.cpp', '<(angle_path)/src/tests/compiler_tests/CollectVariables_test.cpp', '<(angle_path)/src/tests/compiler_tests/ConstantFolding_test.cpp', '<(angle_path)/src/tests/compiler_tests/DebugShaderPrecision_test.cpp', + '<(angle_path)/src/tests/compiler_tests/EmulateGLFragColorBroadcast_test.cpp', '<(angle_path)/src/tests/compiler_tests/ExpressionLimit_test.cpp', '<(angle_path)/src/tests/compiler_tests/EXT_blend_func_extended_test.cpp', '<(angle_path)/src/tests/compiler_tests/FragDepth_test.cpp', @@ -54,7 +54,10 @@ '<(angle_path)/src/tests/compiler_tests/MalformedShader_test.cpp', '<(angle_path)/src/tests/compiler_tests/NV_draw_buffers_test.cpp', '<(angle_path)/src/tests/compiler_tests/Pack_Unpack_test.cpp', + '<(angle_path)/src/tests/compiler_tests/PruneEmptyDeclarations_test.cpp', '<(angle_path)/src/tests/compiler_tests/PruneUnusedFunctions_test.cpp', + '<(angle_path)/src/tests/compiler_tests/QualificationOrderESSL31_test.cpp', + '<(angle_path)/src/tests/compiler_tests/QualificationOrder_test.cpp', '<(angle_path)/src/tests/compiler_tests/RecordConstantPrecision_test.cpp', '<(angle_path)/src/tests/compiler_tests/RemovePow_test.cpp', '<(angle_path)/src/tests/compiler_tests/ShaderExtension_test.cpp', @@ -62,6 +65,7 @@ '<(angle_path)/src/tests/compiler_tests/ShCompile_test.cpp', '<(angle_path)/src/tests/compiler_tests/TypeTracking_test.cpp', '<(angle_path)/src/tests/compiler_tests/VariablePacker_test.cpp', + '<(angle_path)/src/tests/compiler_tests/WorkGroupSize_test.cpp', '<(angle_path)/src/tests/preprocessor_tests/char_test.cpp', '<(angle_path)/src/tests/preprocessor_tests/comment_test.cpp', '<(angle_path)/src/tests/preprocessor_tests/define_test.cpp', @@ -135,6 +139,10 @@ ['OS=="win"', { # TODO(cwallez): make this angle_enable_hlsl instead (requires gyp file refactoring) + 'defines': + [ + 'ANGLE_ENABLE_HLSL', + ], 'sources': [ '<@(angle_unittests_hlsl_sources)', diff --git a/chromium/third_party/angle/src/tests/deqp.gypi b/chromium/third_party/angle/src/tests/deqp.gypi index 58803afc803..2bf6c5648c1 100644 --- a/chromium/third_party/angle/src/tests/deqp.gypi +++ b/chromium/third_party/angle/src/tests/deqp.gypi @@ -11,12 +11,10 @@ 'variables': { 'angle_build_winrt%': 0, - 'angle_standalone%': 0, }, # Copy conditionally-set variables to the outer variables dict. 'angle_build_winrt%': '<(angle_build_winrt)', - 'angle_standalone%': '<(angle_standalone)', 'deqp_path': '<(DEPTH)/third_party/deqp/src', 'libpng_path': '<(DEPTH)/third_party/libpng', @@ -56,10 +54,12 @@ ], 'deqp_defines': [ + 'DEQP_SUPPORT_GLES31=1', 'DEQP_SUPPORT_GLES3=1', 'DEQP_SUPPORT_GLES2=1', 'DEQP_SUPPORT_EGL=1', 'DEQP_TARGET_NAME="angle"', + 'DEQP_GLES31_RUNTIME_LOAD=1', 'DEQP_GLES3_RUNTIME_LOAD=1', 'DEQP_GLES2_RUNTIME_LOAD=1', 'QP_SUPPORT_PNG=1', @@ -605,6 +605,196 @@ '<(deqp_path)/modules/gles3/tes3TestPackage.hpp', '<(deqp_path)/modules/gles3/tes3TestPackageEntry.cpp', ], + 'deqp_gles31_sources': + [ + '<(deqp_path)/modules/gles31/functional/es31fAdvancedBlendTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fAdvancedBlendTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fAndroidExtensionPackES31ATests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fAndroidExtensionPackES31ATests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fAtomicCounterTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fAtomicCounterTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fBasicComputeShaderTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fBasicComputeShaderTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fBooleanStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fBooleanStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fBuiltinPrecisionTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fBuiltinPrecisionTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fComputeShaderBuiltinVarTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fComputeShaderBuiltinVarTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fCopyImageTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fCopyImageTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fDebugTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fDebugTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fDefaultVertexArrayObjectTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fDefaultVertexArrayObjectTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fDrawBuffersIndexedTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fDrawTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fDrawTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fFboColorbufferTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fFboColorbufferTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fFboNoAttachmentTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fFboNoAttachmentTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fFboTestCase.cpp', + '<(deqp_path)/modules/gles31/functional/es31fFboTestCase.hpp', + '<(deqp_path)/modules/gles31/functional/es31fFboTestUtil.cpp', + '<(deqp_path)/modules/gles31/functional/es31fFboTestUtil.hpp', + '<(deqp_path)/modules/gles31/functional/es31fFramebufferDefaultStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fFramebufferDefaultStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fFunctionalTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fFunctionalTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fGeometryShaderTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fGeometryShaderTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fIndexedStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fIndexedStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fIndirectComputeDispatchTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fIndirectComputeDispatchTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fInfoLogQueryShared.cpp', + '<(deqp_path)/modules/gles31/functional/es31fInfoLogQueryShared.hpp', + '<(deqp_path)/modules/gles31/functional/es31fIntegerStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fIntegerStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fInternalFormatQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fInternalFormatQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fLayoutBindingTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fLayoutBindingTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fMultisampleShaderRenderCase.cpp', + '<(deqp_path)/modules/gles31/functional/es31fMultisampleShaderRenderCase.hpp', + '<(deqp_path)/modules/gles31/functional/es31fMultisampleTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fMultisampleTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeAtomicCounterTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeAtomicCounterTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeBufferApiTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeBufferApiTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeFragmentApiTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeFragmentApiTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativePreciseTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativePreciseTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderApiTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderApiTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderDirectiveTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderFunctionTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeStateApiTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeStateApiTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeTestShared.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeTestShared.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeTextureApiTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeTextureApiTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fNegativeVertexArrayApiTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fOpaqueTypeIndexingTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fOpaqueTypeIndexingTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fPrimitiveBoundingBoxTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fPrimitiveBoundingBoxTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceDefinition.cpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceDefinition.hpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.cpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceDefinitionUtil.hpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceQueryTestCase.cpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceQueryTestCase.hpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramInterfaceQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramPipelineStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramPipelineStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramUniformTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fProgramUniformTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSSBOArrayLengthTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSSBOArrayLengthTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSSBOLayoutCase.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSSBOLayoutCase.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSSBOLayoutTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSSBOLayoutTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSampleShadingTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSampleShadingTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSampleVariableTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSampleVariableTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSamplerStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSamplerStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSeparateShaderTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSeparateShaderTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderAtomicOpTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderAtomicOpTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderBuiltinConstantTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderBuiltinConstantTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderCommonFunctionTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderCommonFunctionTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderHelperInvocationTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderHelperInvocationTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderImageLoadStoreTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderImageLoadStoreTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderIntegerFunctionTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderIntegerFunctionTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderMultisampleInterpolationStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderMultisampleInterpolationStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderMultisampleInterpolationTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderMultisampleInterpolationTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderPackingFunctionTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderPackingFunctionTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderSharedVarTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderSharedVarTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderTextureSizeTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fShaderTextureSizeTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fStencilTexturingTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fStencilTexturingTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fSynchronizationTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fSynchronizationTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTessellationGeometryInteractionTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTessellationGeometryInteractionTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTessellationTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTessellationTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureBorderClampTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureBorderClampTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureBufferTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureBufferTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureFilteringTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureFilteringTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureFormatTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureFormatTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureGatherTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureGatherTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureLevelStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureLevelStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureMultisampleTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureMultisampleTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureSpecificationTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureSpecificationTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fTextureStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fUniformBlockTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fUniformBlockTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fUniformLocationTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fUniformLocationTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fVertexAttributeBindingStateQueryTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fVertexAttributeBindingStateQueryTests.hpp', + '<(deqp_path)/modules/gles31/functional/es31fVertexAttributeBindingTests.cpp', + '<(deqp_path)/modules/gles31/functional/es31fVertexAttributeBindingTests.hpp', + '<(deqp_path)/modules/gles31/stress/es31sDrawTests.cpp', + '<(deqp_path)/modules/gles31/stress/es31sDrawTests.hpp', + '<(deqp_path)/modules/gles31/stress/es31sStressTests.cpp', + '<(deqp_path)/modules/gles31/stress/es31sStressTests.hpp', + '<(deqp_path)/modules/gles31/stress/es31sTessellationGeometryInteractionTests.cpp', + '<(deqp_path)/modules/gles31/stress/es31sTessellationGeometryInteractionTests.hpp', + '<(deqp_path)/modules/gles31/stress/es31sVertexAttributeBindingTests.cpp', + '<(deqp_path)/modules/gles31/stress/es31sVertexAttributeBindingTests.hpp', + '<(deqp_path)/modules/gles31/tes31Context.cpp', + '<(deqp_path)/modules/gles31/tes31Context.hpp', + '<(deqp_path)/modules/gles31/tes31InfoTests.cpp', + '<(deqp_path)/modules/gles31/tes31InfoTests.hpp', + '<(deqp_path)/modules/gles31/tes31TestCase.cpp', + '<(deqp_path)/modules/gles31/tes31TestCase.hpp', + '<(deqp_path)/modules/gles31/tes31TestPackage.cpp', + '<(deqp_path)/modules/gles31/tes31TestPackage.hpp', + '<(deqp_path)/modules/gles31/tes31TestPackageEntry.cpp' + ], 'deqp_egl_sources': [ '<(deqp_path)/modules/egl/teglAndroidUtil.cpp', @@ -1000,7 +1190,7 @@ # GoogleTest doesn't support WinRT 'angle_build_deqp_gtest_support%': 1, }], - ['((OS=="win" or OS=="linux" or OS=="mac") and angle_standalone==1 and angle_build_winrt==0)', + ['((OS=="win" or OS=="linux" or OS=="mac") and angle_build_winrt==0)', { # Build the dEQP executables for all standalone Windows/Linux builds except WinRT # GYP doesn't support generating standalone WinRT executables @@ -1053,7 +1243,7 @@ }, 'conditions': [ - ['angle_build_deqp_libraries==1 and angle_standalone==1', + ['angle_build_deqp_libraries==1', { 'targets': [ @@ -1176,7 +1366,7 @@ ], }, ], # targets - }], # angle_build_deqp_libraries==1 and angle_standalone==1 + }], # angle_build_deqp_libraries==1 ['angle_build_deqp_libraries==1', { 'targets': @@ -1326,6 +1516,7 @@ [ 'angle_deqp_decpp', 'angle_deqp_support', + 'angle_libpng', '<(angle_path)/src/angle.gyp:libEGL', '<(angle_path)/util/util.gyp:angle_util', ], @@ -1356,6 +1547,7 @@ 'AdditionalOptions': [ '/bigobj', # needed for glsBuiltinPrecisionTests.cpp + '/wd4251', # needed for angle_util STL objects not having DLL interface ], }, }, @@ -1365,13 +1557,6 @@ ], 'conditions': [ - ['angle_standalone==1', - { - 'dependencies': [ 'angle_libpng' ], - }, - { # angle_standalone!=1 - 'dependencies': [ '<(DEPTH)/third_party/libpng/libpng.gyp:libpng' ], - }], ['OS=="mac"', { 'direct_dependent_settings': @@ -1455,6 +1640,33 @@ }, { + 'target_name': 'angle_deqp_libgles31', + 'type': 'shared_library', + 'dependencies': + [ + 'angle_deqp_libtester', + ], + 'defines': + [ + 'ANGLE_DEQP_GLES31_TESTS', + ], + 'direct_dependent_settings': + { + 'defines': + [ + 'ANGLE_DEQP_GLES31_TESTS', + ], + }, + 'sources': + [ + '<@(deqp_gles31_sources)', + 'deqp_support/angle_deqp_libtester_main.cpp', + 'deqp_support/tcuANGLEPlatform.cpp', + 'deqp_support/tcuANGLEPlatform.h', + ], + }, + + { 'target_name': 'angle_deqp_libegl', 'type': 'shared_library', 'dependencies': @@ -1513,6 +1725,19 @@ }, { + 'target_name': 'angle_deqp_gles31_tests', + 'type': 'executable', + 'dependencies': + [ + 'angle_deqp_libgles31', + ], + 'sources': + [ + 'deqp_support/angle_deqp_tests_main.cpp', + ], + }, + + { 'target_name': 'angle_deqp_egl_tests', 'type': 'executable', 'dependencies': @@ -1538,6 +1763,7 @@ [ 'angle_test_support', '<(angle_path)/util/util.gyp:angle_util', + '<(angle_path)/src/angle.gyp:angle_common', ], 'export_dependent_settings': [ @@ -1644,6 +1870,21 @@ }, { + 'target_name': 'angle_deqp_gtest_gles31_tests', + 'type': 'executable', + 'includes': [ '../../build/common_defines.gypi', ], + 'dependencies': + [ + 'angle_deqp_gtest_support', + 'angle_deqp_libgles31', + ], + 'sources': + [ + 'deqp_support/angle_deqp_gtest_main.cpp', + ], + }, + + { 'target_name': 'angle_deqp_gtest_egl_tests', 'type': 'executable', 'includes': [ '../../build/common_defines.gypi', ], diff --git a/chromium/third_party/angle/src/tests/tests.gyp b/chromium/third_party/angle/src/tests/tests.gyp index 79f7384a58d..c2d18e7898c 100644 --- a/chromium/third_party/angle/src/tests/tests.gyp +++ b/chromium/third_party/angle/src/tests/tests.gyp @@ -51,34 +51,15 @@ { 'target_name': 'angle_test_support', 'type': 'none', - 'conditions': + 'dependencies': [ - ['angle_standalone==1', - { - 'dependencies': [ - 'angle_internal_gmock', - 'angle_internal_gtest', - ], - }, - { - 'dependencies': [ - '<(DEPTH)/testing/gmock.gyp:gmock', - '<(DEPTH)/testing/gtest.gyp:gtest', - ], - 'all_dependent_settings': - { - 'include_dirs': - [ - '<(DEPTH)/testing/gmock/include', - '<(DEPTH)/testing/gtest/include', - ], - }, - }], + 'angle_internal_gmock', + 'angle_internal_gtest', ], }, ], }], - ['angle_standalone==1 and angle_build_winrt==0', + ['angle_build_winrt==0', { 'targets': [ |